From 3a59c7ec4c2677fb83861fcd8fca284b3db46c61 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Mon, 7 Mar 2022 17:51:27 +0100 Subject: [PATCH 1/4] add driveAlias to the graphAPI --- changelog/unreleased/space-aliases.md | 5 ++++ go.mod | 2 +- go.sum | 4 +-- graph/pkg/service/v0/drives.go | 25 +++++++++++-------- .../features/apiSpaces/listSpaces.feature | 2 ++ 5 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 changelog/unreleased/space-aliases.md diff --git a/changelog/unreleased/space-aliases.md b/changelog/unreleased/space-aliases.md new file mode 100644 index 00000000000..4d291c09458 --- /dev/null +++ b/changelog/unreleased/space-aliases.md @@ -0,0 +1,5 @@ +Enhancement: Add space aliases + +Space aliases can be used to resolve spaceIDs in a client. + +https://github.com/owncloud/ocis/pull/3283 diff --git a/go.mod b/go.mod index a593e47f8c9..9a44aa5f8e4 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/blevesearch/bleve/v2 v2.3.1 github.com/coreos/go-oidc/v3 v3.1.0 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 - github.com/cs3org/reva/v2 v2.0.0-20220314085001-8e5b22a20a3f + github.com/cs3org/reva/v2 v2.0.0-20220315083752-d008faf40d48 github.com/disintegration/imaging v1.6.2 github.com/glauth/glauth/v2 v2.0.0-20211021011345-ef3151c28733 github.com/go-chi/chi/v5 v5.0.7 diff --git a/go.sum b/go.sum index 757c94253e4..3734404fa80 100644 --- a/go.sum +++ b/go.sum @@ -341,8 +341,8 @@ github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD9 github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 h1:1jqPH58jCxvbaJ9WLIJ7W2/m622bWS6ChptzljSG6IQ= github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.0.0-20220314085001-8e5b22a20a3f h1:tv7v6OjbFoDFNB2ikGC+LLaWEOIAJnrZjyO5LRTDL0g= -github.com/cs3org/reva/v2 v2.0.0-20220314085001-8e5b22a20a3f/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0= +github.com/cs3org/reva/v2 v2.0.0-20220315083752-d008faf40d48 h1:BLaNoseOPNvE5Khyc0DnUBFb29oiRja1RRCLBQcrjOQ= +github.com/cs3org/reva/v2 v2.0.0-20220315083752-d008faf40d48/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= diff --git a/graph/pkg/service/v0/drives.go b/graph/pkg/service/v0/drives.go index e3e16186164..a82f284223c 100644 --- a/graph/pkg/service/v0/drives.go +++ b/graph/pkg/service/v0/drives.go @@ -218,6 +218,10 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) { csr.Opaque = utils.AppendPlainToOpaque(csr.Opaque, "description", *drive.Description) } + if drive.DriveAlias != nil { + csr.Opaque = utils.AppendPlainToOpaque(csr.Opaque, "spaceAlias", *drive.DriveAlias) + } + resp, err := client.CreateStorageSpace(r.Context(), &csr) if err != nil { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) @@ -303,24 +307,19 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) { } } - // Note: this is the Opaque prop of the space itself - opaque := make(map[string]*types.OpaqueEntry) if drive.Description != nil { - opaque["description"] = &types.OpaqueEntry{ - Decoder: "plain", - Value: []byte(*drive.Description), - } + updateSpaceRequest.StorageSpace.Opaque = utils.AppendPlainToOpaque(updateSpaceRequest.StorageSpace.Opaque, "description", *drive.Description) + } + + if drive.DriveAlias != nil { + updateSpaceRequest.StorageSpace.Opaque = utils.AppendPlainToOpaque(updateSpaceRequest.StorageSpace.Opaque, "spaceAlias", *drive.DriveAlias) } for _, special := range drive.Special { if special.Id != nil { - opaque[*special.SpecialFolder.Name] = &types.OpaqueEntry{ - Decoder: "plain", - Value: []byte(*special.Id), - } + updateSpaceRequest.StorageSpace.Opaque = utils.AppendPlainToOpaque(updateSpaceRequest.StorageSpace.Opaque, *special.SpecialFolder.Name, *special.Id) } } - updateSpaceRequest.StorageSpace.Opaque = &types.Opaque{Map: opaque} if drive.Name != nil { updateSpaceRequest.StorageSpace.Name = *drive.Name @@ -508,6 +507,10 @@ func (g Graph) cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.S drive.Description = libregraph.PtrString(string(description.Value)) } + if alias, ok := space.Opaque.Map["spaceAlias"]; ok { + drive.DriveAlias = libregraph.PtrString(string(alias.Value)) + } + if v, ok := space.Opaque.Map["trashed"]; ok { deleted := &libregraph.Deleted{} deleted.SetState(string(v.Value)) diff --git a/tests/acceptance/features/apiSpaces/listSpaces.feature b/tests/acceptance/features/apiSpaces/listSpaces.feature index 920700154a8..b0af266c50d 100644 --- a/tests/acceptance/features/apiSpaces/listSpaces.feature +++ b/tests/acceptance/features/apiSpaces/listSpaces.feature @@ -15,6 +15,7 @@ Feature: List and create spaces And the json responded should contain a space "Alice Hansen" with these key and value pairs: | key | value | | driveType | personal | + | driveAlias | personal/Alice | | id | %space_id% | | name | Alice Hansen | | quota@@@state | normal | @@ -61,6 +62,7 @@ Feature: List and create spaces And the json responded should contain a space "Project Mars" with these key and value pairs: | key | value | | driveType | project | + | driveAlias | project/project-mars | | name | Project Mars | | quota@@@total | 1000000000 | | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% | From 0773b6632574795cea60e0a3cd44b72495faf232 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 16 Mar 2022 15:01:12 +0100 Subject: [PATCH 2/4] add space alias config to s3ng and ocis driver --- go.mod | 2 +- go.sum | 4 +- storage/pkg/command/storagedrivers/user.go | 38 ++++++++++--------- storage/pkg/config/config.go | 22 +++++++++++ storage/pkg/config/defaults/defaultconfig.go | 30 +++++++++------ .../features/apiSpaces/listSpaces.feature | 4 +- 6 files changed, 67 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 9a44aa5f8e4..0a7e1ac7f34 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/blevesearch/bleve/v2 v2.3.1 github.com/coreos/go-oidc/v3 v3.1.0 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 - github.com/cs3org/reva/v2 v2.0.0-20220315083752-d008faf40d48 + github.com/cs3org/reva/v2 v2.0.0-20220316045927-99115670eb33 github.com/disintegration/imaging v1.6.2 github.com/glauth/glauth/v2 v2.0.0-20211021011345-ef3151c28733 github.com/go-chi/chi/v5 v5.0.7 diff --git a/go.sum b/go.sum index 3734404fa80..1b077fe8e5f 100644 --- a/go.sum +++ b/go.sum @@ -341,8 +341,8 @@ github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD9 github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 h1:1jqPH58jCxvbaJ9WLIJ7W2/m622bWS6ChptzljSG6IQ= github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.0.0-20220315083752-d008faf40d48 h1:BLaNoseOPNvE5Khyc0DnUBFb29oiRja1RRCLBQcrjOQ= -github.com/cs3org/reva/v2 v2.0.0-20220315083752-d008faf40d48/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0= +github.com/cs3org/reva/v2 v2.0.0-20220316045927-99115670eb33 h1:XK88Fs9FteY9a+iKXqPhUK38zNQbP1jj60zy+Tx7SPI= +github.com/cs3org/reva/v2 v2.0.0-20220316045927-99115670eb33/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= diff --git a/storage/pkg/command/storagedrivers/user.go b/storage/pkg/command/storagedrivers/user.go index 412f08deef6..a15527344c3 100644 --- a/storage/pkg/command/storagedrivers/user.go +++ b/storage/pkg/command/storagedrivers/user.go @@ -89,12 +89,14 @@ func UserDrivers(cfg *config.Config) map[string]interface{} { "userprovidersvc": cfg.Reva.Users.Endpoint, }, "ocis": map[string]interface{}{ - "root": cfg.Reva.UserStorage.OCIS.Root, - "user_layout": cfg.Reva.UserStorage.OCIS.UserLayout, - "share_folder": cfg.Reva.UserStorage.OCIS.ShareFolder, - "treetime_accounting": true, - "treesize_accounting": true, - "permissionssvc": cfg.Reva.Permissions.Endpoint, + "root": cfg.Reva.UserStorage.OCIS.Root, + "user_layout": cfg.Reva.UserStorage.OCIS.UserLayout, + "share_folder": cfg.Reva.UserStorage.OCIS.ShareFolder, + "personalspacealias_template": cfg.Reva.UserStorage.OCIS.PersonalSpaceAliasTemplate, + "generalspacealias_template": cfg.Reva.UserStorage.OCIS.GeneralSpaceAliasTemplate, + "treetime_accounting": true, + "treesize_accounting": true, + "permissionssvc": cfg.Reva.Permissions.Endpoint, }, "s3": map[string]interface{}{ "enable_home": false, @@ -106,17 +108,19 @@ func UserDrivers(cfg *config.Config) map[string]interface{} { "prefix": cfg.Reva.UserStorage.S3.Root, }, "s3ng": map[string]interface{}{ - "root": cfg.Reva.UserStorage.S3NG.Root, - "user_layout": cfg.Reva.UserStorage.S3NG.UserLayout, - "share_folder": cfg.Reva.UserStorage.S3NG.ShareFolder, - "treetime_accounting": true, - "treesize_accounting": true, - "permissionssvc": cfg.Reva.Permissions.Endpoint, - "s3.region": cfg.Reva.UserStorage.S3NG.Region, - "s3.access_key": cfg.Reva.UserStorage.S3NG.AccessKey, - "s3.secret_key": cfg.Reva.UserStorage.S3NG.SecretKey, - "s3.endpoint": cfg.Reva.UserStorage.S3NG.Endpoint, - "s3.bucket": cfg.Reva.UserStorage.S3NG.Bucket, + "root": cfg.Reva.UserStorage.S3NG.Root, + "user_layout": cfg.Reva.UserStorage.S3NG.UserLayout, + "share_folder": cfg.Reva.UserStorage.S3NG.ShareFolder, + "personalspacealias_template": cfg.Reva.UserStorage.S3NG.PersonalSpaceAliasTemplate, + "generalspacealias_template": cfg.Reva.UserStorage.S3NG.GeneralSpaceAliasTemplate, + "treetime_accounting": true, + "treesize_accounting": true, + "permissionssvc": cfg.Reva.Permissions.Endpoint, + "s3.region": cfg.Reva.UserStorage.S3NG.Region, + "s3.access_key": cfg.Reva.UserStorage.S3NG.AccessKey, + "s3.secret_key": cfg.Reva.UserStorage.S3NG.SecretKey, + "s3.endpoint": cfg.Reva.UserStorage.S3NG.Endpoint, + "s3.bucket": cfg.Reva.UserStorage.S3NG.Bucket, }, } } diff --git a/storage/pkg/config/config.go b/storage/pkg/config/config.go index 086f4b9ef23..df983cb340e 100644 --- a/storage/pkg/config/config.go +++ b/storage/pkg/config/config.go @@ -241,6 +241,12 @@ type DriverCommon struct { UserLayout string `ocisConfig:"user_layout"` // EnableHome enables the creation of home directories. EnableHome bool `ocisConfig:"enable_home"` + // PersonalSpaceAliasTemplate contains the template used to construct + // the personal space alias, eg: `"{{.SpaceType}}/{{.User.Username | lower}}"` + PersonalSpaceAliasTemplate string `ocisConfig:"personalspacealias_template"` + // GeneralSpaceAliasTemplate contains the template used to construct + // the general space alias, eg: `{{.SpaceType}}/{{.SpaceName | replace " " "-" | lower}}` + GeneralSpaceAliasTemplate string `ocisConfig:"generalspacealias_template"` } // DriverEOS defines the available EOS driver configuration. @@ -1528,6 +1534,14 @@ func structMappings(cfg *Config) []shared.EnvBinding { EnvVars: []string{"STORAGE_USERS_DRIVER_OCIS_SHARE_FOLDER"}, Destination: &cfg.Reva.UserStorage.OCIS.ShareFolder, }, + { + EnvVars: []string{"STORAGE_USERS_DRIVER_OCIS_PERSONAL_SPACE_ALIAS_TEMPLATE"}, + Destination: &cfg.Reva.UserStorage.OCIS.PersonalSpaceAliasTemplate, + }, + { + EnvVars: []string{"STORAGE_USERS_DRIVER_OCIS_GENERAL_SPACE_ALIAS_TEMPLATE"}, + Destination: &cfg.Reva.UserStorage.OCIS.GeneralSpaceAliasTemplate, + }, // driver owncloud sql { EnvVars: []string{"STORAGE_USERS_DRIVER_OWNCLOUDSQL_DATADIR"}, @@ -1601,6 +1615,14 @@ func structMappings(cfg *Config) []shared.EnvBinding { EnvVars: []string{"STORAGE_USERS_DRIVER_S3NG_SHARE_FOLDER"}, Destination: &cfg.Reva.UserStorage.S3NG.ShareFolder, }, + { + EnvVars: []string{"STORAGE_USERS_DRIVER_S3NG_PERSONAL_SPACE_ALIAS_TEMPLATE"}, + Destination: &cfg.Reva.UserStorage.S3NG.PersonalSpaceAliasTemplate, + }, + { + EnvVars: []string{"STORAGE_USERS_DRIVER_S3NG_GENERAL_SPACE_ALIAS_TEMPLATE"}, + Destination: &cfg.Reva.UserStorage.S3NG.GeneralSpaceAliasTemplate, + }, { EnvVars: []string{"STORAGE_USERS_DRIVER_S3NG_REGION"}, Destination: &cfg.Reva.UserStorage.S3NG.Region, diff --git a/storage/pkg/config/defaults/defaultconfig.go b/storage/pkg/config/defaults/defaultconfig.go index 142b05db7ff..a24319458e9 100644 --- a/storage/pkg/config/defaults/defaultconfig.go +++ b/storage/pkg/config/defaults/defaultconfig.go @@ -9,11 +9,13 @@ import ( ) const ( - defaultPublicURL = "https://localhost:9200" - defaultShareFolder = "/Shares" - defaultStorageNamespace = "/users/{{.Id.OpaqueId}}" - defaultGatewayAddr = "127.0.0.1:9142" - defaultUserLayout = "{{.Id.OpaqueId}}" + defaultPublicURL = "https://localhost:9200" + defaultShareFolder = "/Shares" + defaultStorageNamespace = "/users/{{.Id.OpaqueId}}" + defaultGatewayAddr = "127.0.0.1:9142" + defaultUserLayout = "{{.Id.OpaqueId}}" + defaultPersonalSpaceAliasTemplate = "{{.SpaceType}}/{{.User.Username | lower}}" + defaultGeneralSpaceAliasTemplate = "{{.SpaceType}}/{{.SpaceName | replace \" \" \"-\" | lower}}" ) func FullDefaultConfig() *config.Config { @@ -145,10 +147,12 @@ func DefaultConfig() *config.Config { }, S3NG: config.DriverS3NG{ DriverCommon: config.DriverCommon{ - Root: path.Join(defaults.BaseDataPath(), "storage", "users"), - ShareFolder: defaultShareFolder, - UserLayout: defaultUserLayout, - EnableHome: false, + Root: path.Join(defaults.BaseDataPath(), "storage", "users"), + ShareFolder: defaultShareFolder, + UserLayout: defaultUserLayout, + PersonalSpaceAliasTemplate: defaultPersonalSpaceAliasTemplate, + GeneralSpaceAliasTemplate: defaultGeneralSpaceAliasTemplate, + EnableHome: false, }, Region: "default", AccessKey: "", @@ -158,9 +162,11 @@ func DefaultConfig() *config.Config { }, OCIS: config.DriverOCIS{ DriverCommon: config.DriverCommon{ - Root: path.Join(defaults.BaseDataPath(), "storage", "users"), - ShareFolder: defaultShareFolder, - UserLayout: defaultUserLayout, + Root: path.Join(defaults.BaseDataPath(), "storage", "users"), + ShareFolder: defaultShareFolder, + UserLayout: defaultUserLayout, + PersonalSpaceAliasTemplate: defaultPersonalSpaceAliasTemplate, + GeneralSpaceAliasTemplate: defaultGeneralSpaceAliasTemplate, }, }, }, diff --git a/tests/acceptance/features/apiSpaces/listSpaces.feature b/tests/acceptance/features/apiSpaces/listSpaces.feature index b0af266c50d..7c6a01f3392 100644 --- a/tests/acceptance/features/apiSpaces/listSpaces.feature +++ b/tests/acceptance/features/apiSpaces/listSpaces.feature @@ -15,7 +15,7 @@ Feature: List and create spaces And the json responded should contain a space "Alice Hansen" with these key and value pairs: | key | value | | driveType | personal | - | driveAlias | personal/Alice | + | driveAlias | personal/alice | | id | %space_id% | | name | Alice Hansen | | quota@@@state | normal | @@ -100,6 +100,7 @@ Feature: List and create spaces And the json responded should contain a space "Project Venus" with these key and value pairs: | key | value | | driveType | project | + | driveAlias | project/project-venus | | name | Project Venus | | quota@@@total | 2000 | | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% | @@ -107,6 +108,7 @@ Feature: List and create spaces Then the json responded should contain a space "Project Venus" with these key and value pairs: | key | value | | driveType | project | + | driveAlias | project/project-venus | | name | Project Venus | | quota@@@total | 2000 | | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% | From ec93e423bdd1dfb4e649ee665032247437d64b86 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 16 Mar 2022 17:25:34 +0100 Subject: [PATCH 3/4] fix expected failures --- tests/acceptance/expected-failures-API-on-OCIS-storage.md | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md index c5630848c3c..5948ee21e21 100644 --- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md @@ -1859,7 +1859,6 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers #### [status does not have new product data item](https://github.com/owncloud/ocis/issues/3317) - [apiCapabilities/capabilities.feature:959](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiCapabilities/capabilities.feature#L959) -- [apiMain/status.feature:5](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/status.feature#L5) Note: always have an empty line at the end of this file. The bash script that processes this file requires that the last line has a newline on the end. From 7a0e28a42076cfcc9d477375606c4f6743d390da Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 16 Mar 2022 20:15:23 +0100 Subject: [PATCH 4/4] add drive alias to unit tests --- graph/pkg/service/v0/graph_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/graph/pkg/service/v0/graph_test.go b/graph/pkg/service/v0/graph_test.go index e475af9e3f9..30c1160772d 100644 --- a/graph/pkg/service/v0/graph_test.go +++ b/graph/pkg/service/v0/graph_test.go @@ -10,6 +10,7 @@ import ( gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" "github.com/cs3org/reva/v2/pkg/rgrpc/status" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -116,6 +117,12 @@ var _ = Describe("Graph", func() { OpaqueId: "bopaqueid", }, Name: "bspacename", + Opaque: &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spaceAlias": {Decoder: "plain", Value: []byte("bspacetype/bspacename")}, + "etag": {Decoder: "plain", Value: []byte("123456789")}, + }, + }, }, { Id: &provider.StorageSpaceId{OpaqueId: "aspaceid"}, @@ -125,6 +132,12 @@ var _ = Describe("Graph", func() { OpaqueId: "anopaqueid", }, Name: "aspacename", + Opaque: &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spaceAlias": {Decoder: "plain", Value: []byte("aspacetype/aspacename")}, + "etag": {Decoder: "plain", Value: []byte("101112131415")}, + }, + }, }, }, }, nil) @@ -146,19 +159,23 @@ var _ = Describe("Graph", func() { { "value":[ { + "driveAlias":"aspacetype/aspacename", "driveType":"aspacetype", "id":"aspaceid", "name":"aspacename", "root":{ + "eTag":"101112131415", "id":"aspaceid!anopaqueid", "webDavUrl":"https://localhost:9200/dav/spaces/aspaceid" } }, { + "driveAlias":"bspacetype/bspacename", "driveType":"bspacetype", "id":"bspaceid", "name":"bspacename", "root":{ + "eTag":"123456789", "id":"bspaceid!bopaqueid", "webDavUrl":"https://localhost:9200/dav/spaces/bspaceid" }