Merge branch 'master' into FixFlakySpacesYamlTest

This commit is contained in:
jkoberg
2022-01-20 10:02:55 +01:00
11 changed files with 244 additions and 53 deletions
+15 -6
View File
@@ -7,6 +7,7 @@ OC_CI_GOLANG = "owncloudci/golang:1.17"
OC_CI_NODEJS = "owncloudci/nodejs:14"
OC_CI_PHP = "owncloudci/php:7.4"
OC_CI_WAIT_FOR = "owncloudci/wait-for:latest"
OC_TESTING_MIDDLEWARE = "owncloud/owncloud-test-middleware:1.2.0"
MINIO_MC = "minio/mc:RELEASE.2021-10-07T04-19-58Z"
REDIS = "redis:6-alpine"
@@ -356,7 +357,12 @@ def uploadScanResults(ctx):
"SONAR_PULL_REQUEST_KEY": "%s" % (ctx.build.ref.replace("refs/pull/", "").split("/")[0]),
})
repo_slug = ctx.build.source_repo if ctx.build.source_repo else ctx.repo.slug
fork_handling = []
if ctx.build.source_repo != "" and ctx.build.source_repo != ctx.repo.slug:
fork_handling = [
"git remote add fork https://github.com/%s.git" % (ctx.build.source_repo),
"git fetch fork",
]
return {
"kind": "pipeline",
@@ -374,9 +380,13 @@ def uploadScanResults(ctx):
"name": "clone",
"image": "alpine/git:latest",
"commands": [
"git clone https://github.com/%s.git ." % (repo_slug),
"git checkout $DRONE_COMMIT",
],
# Always use the owncloud/ocis repository as base to have an up to date default branch.
# This is needed for the skipIfUnchanged step, since it references a commit on master (which could be absent on a fork)
"git clone https://github.com/%s.git ." % (ctx.repo.slug),
] + fork_handling +
[
"git checkout $DRONE_COMMIT",
],
},
] + skipIfUnchanged(ctx, "unit-tests") + [
{
@@ -1443,8 +1453,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []):
def middlewareService():
return [{
"name": "middleware",
"image": "owncloud/owncloud-test-middleware",
"pull": "always",
"image": OC_TESTING_MIDDLEWARE,
"environment": {
"BACKEND_HOST": "https://ocis-server:9200",
"OCIS_REVA_DATA_ROOT": "/srv/app/tmp/ocis/storage/owncloud/",
+7
View File
@@ -18,6 +18,7 @@ The following sections list the changes for unreleased.
* Enhancement - Add spaces capability: [#2931](https://github.com/owncloud/ocis/pull/2931)
* Enhancement - Support signature auth in the public share auth middleware: [#2831](https://github.com/owncloud/ocis/pull/2831)
* Enhancement - Update REVA to v1.16.1-0.20220112085026-07451f6cd806: [#2953](https://github.com/owncloud/ocis/pull/2953)
* Enhancement - Add endpoint to retrieve a single space: [#2978](https://github.com/owncloud/ocis/pull/2978)
* Enhancement - Add filter by driveType and id to /me/drives: [#2946](https://github.com/owncloud/ocis/pull/2946)
* Enhancement - Update REVA to xxx: [#2878](https://github.com/owncloud/ocis/pull/2878)
* Enhancement - Update ownCloud Web to v4.8.0: [#2895](https://github.com/owncloud/ocis/pull/2895)
@@ -107,6 +108,12 @@ The following sections list the changes for unreleased.
https://github.com/owncloud/ocis/pull/2953
* Enhancement - Add endpoint to retrieve a single space: [#2978](https://github.com/owncloud/ocis/pull/2978)
We added the endpoint ``/drives/{driveID}`` to get a single space by id from the server.
https://github.com/owncloud/ocis/pull/2978
* Enhancement - Add filter by driveType and id to /me/drives: [#2946](https://github.com/owncloud/ocis/pull/2946)
We added two possible filter terms (driveType, id) to the /me/drives endpoint on the graph api.
@@ -0,0 +1,5 @@
Enhancement: Add endpoint to retrieve a single space
We added the endpoint ``/drives/{driveID}`` to get a single space by id from the server.
https://github.com/owncloud/ocis/pull/2978
@@ -63,7 +63,7 @@ services:
OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test}
OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose
PROXY_TLS: "false" # do not use SSL between Traefik and oCIS
ACCOUNTS_DEMO_USERS_AND_GROUPS: false # don't generate demo users
ACCOUNTS_DEMO_USERS_AND_GROUPS: "false" # don't generate demo users
# change default secrets
IDP_LDAP_BIND_PASSWORD: ${IDP_LDAP_BIND_PASSWORD:-idp}
STORAGE_LDAP_BIND_PASSWORD: ${STORAGE_LDAP_BIND_PASSWORD:-reva}
+5 -5
View File
@@ -35,7 +35,7 @@ require (
github.com/google/uuid v1.3.0
github.com/gookit/config/v2 v2.0.27
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.3
github.com/iancoleman/strcase v0.2.0
github.com/justinas/alice v1.2.0
github.com/libregraph/lico v0.53.1
@@ -50,7 +50,7 @@ require (
github.com/onsi/gomega v1.17.0
github.com/owncloud/libre-graph-api-go v0.8.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/client_golang v1.12.0
github.com/rs/zerolog v1.26.1
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.3.0
@@ -67,7 +67,7 @@ require (
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5
google.golang.org/grpc v1.43.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0
@@ -141,7 +141,7 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v1.8.8 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/go-cmp v0.5.7 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gookit/goutil v0.4.0 // indirect
github.com/gorilla/schema v1.2.0 // indirect
@@ -229,7 +229,7 @@ require (
golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
golang.org/x/tools v0.1.8 // indirect
+10 -6
View File
@@ -654,8 +654,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@@ -725,8 +726,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2 h1:I/pwhnUln5wbMnTyRbzswA0/JxpK8sZj0aUfI3TV1So=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2/go.mod h1:lsuH8kb4GlMdSlI4alNIBBSAt5CHJtg3i+0WuN9J5YM=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.3 h1:I8MsauTJQXZ8df8qJvEln0kYNc3bSapuaSsEsnFdEFU=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.3/go.mod h1:lZdb/YAJUSj9OqrCHs2ihjtoO3+xK3G53wTYXFWRGDo=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
@@ -1117,8 +1118,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg=
github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -1719,8 +1721,9 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1950,8 +1953,9 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 h1:zzNejm+EgrbLfDZ6lu9Uud2IVvHySPl8vQzf04laR5Q=
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+106 -31
View File
@@ -43,46 +43,20 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
return
}
g.logger.Info().Msg("Calling GetDrives")
g.logger.Info().Interface("query", r.URL.Query()).Msg("Calling GetDrives")
ctx := r.Context()
client := g.GetGatewayClient()
permissions := make(map[string]struct{}, 1)
s := sproto.NewPermissionService("com.owncloud.api.settings", grpc.DefaultClient)
_, err = s.GetPermissionByID(ctx, &sproto.GetPermissionByIDRequest{
PermissionId: settingsSvc.ListAllSpacesPermissionID,
})
// No error means the user has the permission
if err == nil {
permissions[settingsSvc.ListAllSpacesPermissionName] = struct{}{}
}
value, err := json.Marshal(permissions)
if err != nil {
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
filters, err := generateCs3Filters(odataReq)
if err != nil {
g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error")
errorcode.NotSupported.Render(w, r, http.StatusNotImplemented, err.Error())
return
}
res, err := client.ListStorageSpaces(ctx, &storageprovider.ListStorageSpacesRequest{
Opaque: &types.Opaque{Map: map[string]*types.OpaqueEntry{
"permissions": {
Decoder: "json",
Value: value,
},
}},
Filters: filters,
})
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending list storage spaces grpc request")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
@@ -91,7 +65,7 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, &listResponse{})
return
}
g.logger.Error().Err(err).Msg("error sending list storage spaces grpc request")
g.logger.Error().Err(err).Msg(ListStorageSpacesReturnsErr)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
@@ -113,6 +87,75 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, &listResponse{Value: files})
}
// GetSingleDrive does a lookup of a single space by spaceId
func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
driveID := chi.URLParam(r, "driveID")
if driveID == "" {
err := fmt.Errorf("no valid space id retrieved")
g.logger.Err(err)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
g.logger.Info().Str("driveID", driveID).Msg("Calling GetSingleDrive")
ctx := r.Context()
filters := []*storageprovider.ListStorageSpacesRequest_Filter{
{
Type: storageprovider.ListStorageSpacesRequest_Filter_TYPE_ID,
Term: &storageprovider.ListStorageSpacesRequest_Filter_Id{
Id: &storageprovider.StorageSpaceId{
OpaqueId: driveID,
},
},
},
}
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
switch {
case err != nil:
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
// the client is doing a lookup for a specific space, therefore we need to return
// not found to the caller
g.logger.Error().Str("driveID", driveID).Msg(fmt.Sprintf(NoSpaceFoundMessage, driveID))
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf(NoSpaceFoundMessage, driveID))
return
}
g.logger.Error().Err(err).Msg(ListStorageSpacesReturnsErr)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
wdu, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath)
if err != nil {
g.logger.Error().Err(err).Msg("error parsing url")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
spaces, err := g.formatDrives(ctx, wdu, res.StorageSpaces)
if err != nil {
g.logger.Error().Err(err).Msg("error encoding response")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
switch num := len(spaces); {
case num == 0:
g.logger.Error().Str("driveID", driveID).Msg("no space found")
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf(NoSpaceFoundMessage, driveID))
return
case num == 1:
render.Status(r, http.StatusOK)
render.JSON(w, r, spaces[0])
default:
g.logger.Error().Int("number", num).Msg("expected to find a single space but found more")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "expected to find a single space but found more")
return
}
}
// CreateDrive creates a storage drive (space).
func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
us, ok := ctxpkg.ContextGetUser(r.Context())
@@ -340,6 +383,38 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, mds []*storag
return responses, nil
}
// ListStorageSpacesWithFilters List Storage Spaces using filters
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter) (*storageprovider.ListStorageSpacesResponse, error) {
client := g.GetGatewayClient()
permissions := make(map[string]struct{}, 1)
s := sproto.NewPermissionService("com.owncloud.api.settings", grpc.DefaultClient)
_, err := s.GetPermissionByID(ctx, &sproto.GetPermissionByIDRequest{
PermissionId: settingsSvc.ListAllSpacesPermissionID,
})
// No error means the user has the permission
if err == nil {
permissions[settingsSvc.ListAllSpacesPermissionName] = struct{}{}
}
value, err := json.Marshal(permissions)
if err != nil {
return nil, err
}
res, err := client.ListStorageSpaces(ctx, &storageprovider.ListStorageSpacesRequest{
Opaque: &types.Opaque{Map: map[string]*types.OpaqueEntry{
"permissions": {
Decoder: "json",
Value: value,
},
}},
Filters: filters,
})
return res, err
}
func cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
rootID := space.Root.StorageId + "!" + space.Root.OpaqueId
if space.Root.StorageId == space.Root.OpaqueId {
+6
View File
@@ -85,3 +85,9 @@ func (g Graph) GetHTTPClient() HTTPClient {
type listResponse struct {
Value interface{} `json:"value,omitempty"`
}
const (
NoSpaceFoundMessage = "space with id `%s` not found"
ListStorageSpacesTransportErr = "transport error sending list storage spaces grpc request"
ListStorageSpacesReturnsErr = "list storage spaces grpc request returns an errorcode in the response"
)
+1
View File
@@ -117,6 +117,7 @@ func NewService(opts ...Option) Service {
r.Post("/", svc.CreateDrive)
r.Route("/{driveID}", func(r chi.Router) {
r.Patch("/", svc.UpdateDrive)
r.Get("/", svc.GetSingleDrive)
})
})
})
@@ -79,3 +79,35 @@ Feature: List and create spaces
| name | Project Venus |
| quota@@@total | 2000 |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
Scenario: A user can list his personal space via multiple endpoints
When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'personal'"
Then the json responded should contain a space "Alice Hansen" with these key and value pairs:
| key | value |
| driveType | personal |
| name | Alice Hansen |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
When user "Alice" looks up the single space "Alice Hansen" via the GraphApi by using its id
Then the json responded should contain a space "Alice Hansen" with these key and value pairs:
| key | value |
| driveType | personal |
| name | Alice Hansen |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
Scenario: A user can list his created spaces via multiple endpoints
Given the administrator has given "Alice" the role "Admin" using the settings api
When user "Alice" creates a space "Project Venus" of type "project" with quota "2000" using the GraphApi
Then the HTTP status code should be "201"
And the json responded should contain a space "Project Venus" with these key and value pairs:
| key | value |
| driveType | project |
| name | Project Venus |
| quota@@@total | 2000 |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
When user "Alice" looks up the single space "Project Venus" via the GraphApi by using its id
Then the json responded should contain a space "Project Venus" with these key and value pairs:
| key | value |
| driveType | project |
| name | Project Venus |
| quota@@@total | 2000 |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
@@ -232,7 +232,7 @@ class SpacesContext implements Context {
}
/**
* Send Graph List Spaces Request
* Send Graph List My Spaces Request
*
* @param string $user
* @param string $password
@@ -245,7 +245,7 @@ class SpacesContext implements Context {
*
* @throws GuzzleException
*/
public function listSpacesRequest(
public function listMySpacesRequest(
string $user,
string $password,
string $urlArguments = '',
@@ -258,6 +258,34 @@ class SpacesContext implements Context {
return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body);
}
/**
* Send Graph List Single Space Request
*
* @param string $user
* @param string $password
* @param string $urlArguments
* @param string $xRequestId
* @param array $body
* @param array $headers
*
* @return ResponseInterface
*
* @throws GuzzleException
*/
public function listSingleSpaceRequest(
string $user,
string $password,
string $spaceId,
string $urlArguments = '',
string $xRequestId = '',
array $body = [],
array $headers = []
): ResponseInterface {
$fullUrl = $this->baseUrl . "/graph/v1.0/drives/" . $spaceId . "/" . $urlArguments;
return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body);
}
/**
* Send Graph Create Space Request
*
@@ -342,7 +370,7 @@ class SpacesContext implements Context {
*/
public function theUserListsAllHisAvailableSpacesUsingTheGraphApi(string $user): void {
$this->featureContext->setResponse(
$this->listSpacesRequest(
$this->listMySpacesRequest(
$user,
$this->featureContext->getPasswordForUser($user)
)
@@ -362,7 +390,7 @@ class SpacesContext implements Context {
*/
public function theUserListsAllHisAvailableSpacesUsingTheGraphApiWithFilter(string $user, string $query): void {
$this->featureContext->setResponse(
$this->listSpacesRequest(
$this->listMySpacesRequest(
$user,
$this->featureContext->getPasswordForUser($user),
"?". $query
@@ -370,6 +398,30 @@ class SpacesContext implements Context {
);
}
/**
* @When /^user "([^"]*)" looks up the single space "([^"]*)" via the GraphApi by using its id$/
*
* @param string $user
* @param string $query
*
* @return void
*
* @throws GuzzleException
*/
public function theUserLooksUpTheSingleSpaceUsingTheGraphApiByUsingItsId(string $user, string $spaceName): void {
$space = $this->getSpaceByName($user, $spaceName);
Assert::assertIsArray($space);
Assert::assertNotEmpty($spaceId = $space["id"]);
Assert::assertNotEmpty($spaceWebDavUrl = $space["root"]["webDavUrl"]);
$this->featureContext->setResponse(
$this->listSingleSpaceRequest(
$user,
$this->featureContext->getPasswordForUser($user),
$spaceId
)
);
}
/**
* @When /^user "([^"]*)" creates a space "([^"]*)" of type "([^"]*)" with the default quota using the GraphApi$/
*