From 1edc93c9a2dafd25904f6cac648bb37b1cf845b8 Mon Sep 17 00:00:00 2001 From: ryanfkeepers Date: Tue, 11 Apr 2023 16:45:04 -0600 Subject: [PATCH] standardize around site names without host Standardize around normalizing site names to not include the host portion, and only include the two following uuids, since those suffice as a unique id for graph lookups and will remain stable. --- src/internal/connector/discovery/api/sites.go | 35 +++++++++++++++++-- src/internal/connector/sharepoint/queries.go | 28 --------------- src/internal/operations/backup.go | 2 +- src/internal/tester/resource_owners.go | 30 ++++++++++++++-- 4 files changed, 60 insertions(+), 35 deletions(-) delete mode 100644 src/internal/connector/sharepoint/queries.go diff --git a/src/internal/connector/discovery/api/sites.go b/src/internal/connector/discovery/api/sites.go index f45b2af39..c7b611690 100644 --- a/src/internal/connector/discovery/api/sites.go +++ b/src/internal/connector/discovery/api/sites.go @@ -76,6 +76,7 @@ func (c Sites) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Siteable, return true } + s = normalizeSiteableID(s) us = append(us, s) return true @@ -109,12 +110,16 @@ func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable, ctx = clues.Add(ctx, "given_site_id", identifier) if siteIDRE.MatchString(identifier) { + identifier = normalizeID(identifier) + resp, err = c.stable.Client().SitesById(identifier).Get(ctx, nil) if err != nil { return nil, graph.Wrap(ctx, err, "getting site by id") } - return resp, err + resp = normalizeSiteableID(resp) + + return resp, nil } // if the id is not a standard sharepoint ID, assume it's a url. @@ -142,7 +147,9 @@ func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable, return nil, graph.Wrap(ctx, err, "getting site by weburl") } - return resp, err + resp = normalizeSiteableID(resp) + + return resp, nil } // GetIDAndName looks up the site matching the given ID, and returns @@ -154,7 +161,7 @@ func (c Sites) GetIDAndName(ctx context.Context, siteID string) (string, string, return "", "", err } - return ptr.Val(s.GetId()), ptr.Val(s.GetWebUrl()), nil + return ptr.Val(normalizeSiteableID(s).GetId()), ptr.Val(s.GetWebUrl()), nil } // --------------------------------------------------------------------------- @@ -203,3 +210,25 @@ func validateSite(item any) (models.Siteable, error) { return m, nil } + +// sets the siteable's id to the normalizedID. +func normalizeSiteableID(s models.Siteable) models.Siteable { + id := ptr.Val(s.GetId()) + id = normalizeID(id) + s.SetId(ptr.To(id)) + + return s +} + +// the standard sharepoint id is a combination of `{hostname},{spsite-id},{spweb-id}` +// the hostname is subject to change, making this id non-stable. Lucky for us, the +// latter two parts (`{spsite-id},{spweb-id}`) can be used as the site ID on their own. +func normalizeID(id string) string { + if !siteIDRE.MatchString(id) { + // do nothing if the site is already not in a + // {hostname},{uuid},{uuid} format + return id + } + + return strings.Join(strings.Split(id, ",")[1:], ",") +} diff --git a/src/internal/connector/sharepoint/queries.go b/src/internal/connector/sharepoint/queries.go deleted file mode 100644 index 867165075..000000000 --- a/src/internal/connector/sharepoint/queries.go +++ /dev/null @@ -1,28 +0,0 @@ -package sharepoint - -import ( - "context" - - "github.com/microsoft/kiota-abstractions-go/serialization" - "github.com/microsoftgraph/msgraph-sdk-go/sites" - - "github.com/alcionai/corso/src/internal/connector/graph" -) - -// GetAllSitesForTenant makes a GraphQuery request retrieving all sites in the tenant. -// Due to restrictions in filter capabilities for site queries, the returned iterable -// will contain all personal sites for all users in the org. -func GetAllSitesForTenant(ctx context.Context, gs graph.Servicer) (serialization.Parsable, error) { - options := &sites.SitesRequestBuilderGetRequestConfiguration{ - QueryParameters: &sites.SitesRequestBuilderGetQueryParameters{ - Select: []string{"id", "name", "weburl"}, - }, - } - - ss, err := gs.Client().Sites().Get(ctx, options) - if err != nil { - return nil, graph.Wrap(ctx, err, "getting sites") - } - - return ss, nil -} diff --git a/src/internal/operations/backup.go b/src/internal/operations/backup.go index 0236c1c12..074cba1df 100644 --- a/src/internal/operations/backup.go +++ b/src/internal/operations/backup.go @@ -303,7 +303,7 @@ func (op *BackupOperation) do( } func makeFallbackReasons(sel selectors.Selector) []kopia.Reason { - if sel.PathService() != path.SharePointService { + if sel.DiscreteOwner != sel.DiscreteOwnerName { return selectorToReasons(sel, true) } diff --git a/src/internal/tester/resource_owners.go b/src/internal/tester/resource_owners.go index 85c8ae5b7..49bc59f6b 100644 --- a/src/internal/tester/resource_owners.go +++ b/src/internal/tester/resource_owners.go @@ -81,7 +81,15 @@ func LoadTestM365SiteID(t *testing.T) string { cfg, err := readTestConfig() require.NoError(t, err, "retrieving load test m365 site id from test configuration", clues.ToCore(err)) - return cfg[TestCfgSiteID] + id := cfg[TestCfgSiteID] + parts := strings.Split(id, ",") + + if len(parts) < 3 { + return id + } + + // normalize the site url to match the same expectations as the API + return strings.Join(parts[1:], ",") } // LoadTestM365UserID returns an userID string representing the m365UserID @@ -113,7 +121,15 @@ func LoadTestM365OrgSites(t *testing.T) []string { // return strings.Split(sites, ",") - return []string{cfg[TestCfgSiteID]} + id := cfg[TestCfgSiteID] + parts := strings.Split(id, ",") + + if len(parts) < 3 { + return []string{id} + } + + // normalize the site url to match the same expectations as the API + return []string{strings.Join(parts[1:], ",")} } // expects cfg value to be a string representing an array such as: @@ -159,7 +175,15 @@ func M365SiteID(t *testing.T) string { cfg, err := readTestConfig() require.NoError(t, err, "retrieving m365 site id from test configuration", clues.ToCore(err)) - return cfg[TestCfgSiteID] + id := cfg[TestCfgSiteID] + parts := strings.Split(id, ",") + + if len(parts) < 3 { + return id + } + + // normalize the site url to match the same expectations as the API + return strings.Join(parts[1:], ",") } // M365SiteURL returns a site webURL string representing the m365SiteURL described