diff --git a/src/internal/operations/pathtransformer/restore_path_transformer_test.go b/src/internal/operations/pathtransformer/restore_path_transformer_test.go index 49173785a..eead601f5 100644 --- a/src/internal/operations/pathtransformer/restore_path_transformer_test.go +++ b/src/internal/operations/pathtransformer/restore_path_transformer_test.go @@ -36,12 +36,8 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() { repoRef path.Path, unescapedFolders ...string, ) string { - return path.Builder{}. - Append( - repoRef.Tenant(), - repoRef.Service().String(), - repoRef.ResourceOwner(), - repoRef.Category().String()). + pfx, _ := repoRef.Halves() + return pfx. Append(unescapedFolders...). String() } diff --git a/src/pkg/path/path.go b/src/pkg/path/path.go index 8138f0f75..3454d1e9e 100644 --- a/src/pkg/path/path.go +++ b/src/pkg/path/path.go @@ -115,6 +115,10 @@ type Path interface { ShortRef() string // ToBuilder returns a Builder instance that represents the current Path. ToBuilder() *Builder + // Halves breaks the path into its prefix (tenant, services, resources, category) + // and suffix (all parts after the prefix). If either half is empty, that half + // returns an empty, non-nil, value. + Halves() (*Builder, Elements) // Every path needs to comply with these funcs to ensure that PII // is appropriately hidden from logging, errors, and other outputs. diff --git a/src/pkg/path/resource_path.go b/src/pkg/path/resource_path.go index 37738131a..1bd380286 100644 --- a/src/pkg/path/resource_path.go +++ b/src/pkg/path/resource_path.go @@ -156,3 +156,17 @@ func (rp dataLayerResourcePath) ToBuilder() *Builder { func (rp *dataLayerResourcePath) UpdateParent(prev, cur Path) bool { return rp.Builder.UpdateParent(prev.ToBuilder(), cur.ToBuilder()) } + +func (rp *dataLayerResourcePath) Halves() (*Builder, Elements) { + pfx, sfx := &Builder{}, Elements{} + + b := rp.Builder + if len(b.elements) > 0 { + lenPfx := 2 + (len(rp.serviceResources) * 2) + + pfx = &Builder{elements: append(Elements{}, b.elements[:lenPfx]...)} + sfx = append(Elements{}, b.elements[lenPfx-1:]...) + } + + return pfx, sfx +} diff --git a/src/pkg/path/resource_path_test.go b/src/pkg/path/resource_path_test.go index 3a7dfd3c3..bc350612c 100644 --- a/src/pkg/path/resource_path_test.go +++ b/src/pkg/path/resource_path_test.go @@ -678,3 +678,57 @@ func (suite *PopulatedDataLayerResourcePath) TestUpdateParent_NoopsNils() { }) } } + +func (suite *PopulatedDataLayerResourcePath) TestHalves() { + t := suite.T() + + onlyPrefix, err := path.BuildPrefix( + "titd", + []path.ServiceResource{{path.ExchangeService, "pr"}}, + path.ContactsCategory) + require.NoError(t, err, clues.ToCore(err)) + + fullPath, err := path.Build( + "tid", + []path.ServiceResource{{path.ExchangeService, "pr"}}, + path.ContactsCategory, + true, + "fld", "item") + require.NoError(t, err, clues.ToCore(err)) + + table := []struct { + name string + dlrp path.Path + expectPfx *path.Builder + expectSfx path.Elements + }{ + { + name: "only prefix", + dlrp: onlyPrefix, + expectPfx: path.Builder{}.Append( + "tid", + path.ExchangeService.String(), + "pr", + path.ContactsCategory.String()), + expectSfx: path.Elements{}, + }, + { + name: "full path", + dlrp: fullPath, + expectPfx: path.Builder{}.Append( + "tid", + path.ExchangeService.String(), + "pr", + path.ContactsCategory.String()), + expectSfx: path.Elements{"foo", "bar"}, + }, + } + for _, test := range table { + suite.Run(test.name, func() { + t := suite.T() + pfx, sfx := test.dlrp.Halves() + assert.Equal(t, test.expectPfx, pfx, "prefix") + assert.Equal(t, test.expectSfx, sfx, "suffix") + }) + } +}