Merge branch 'master' into metadata-gateway

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Jörn Friedrich Dreyer
2022-05-02 10:33:50 +00:00
13 changed files with 154 additions and 53 deletions
+9
View File
@@ -11,6 +11,7 @@ The following sections list the changes for unreleased.
* Bugfix - URL encode the webdav url in the graph API: [#3597](https://github.com/owncloud/ocis/pull/3597)
* Change - Load configuration files just from one directory: [#3587](https://github.com/owncloud/ocis/pull/3587)
* Change - Introduce `ocis init` and remove all default secrets: [#3551](https://github.com/owncloud/ocis/pull/3551)
* Change - Reduce drives in graph /me/drives API: [#3629](https://github.com/owncloud/ocis/pull/3629)
* Change - Switched default configuration to use libregraph/idm: [#3331](https://github.com/owncloud/ocis/pull/3331)
* Enhancement - Add capability for public link single file edit: [#6787](https://github.com/owncloud/web/pull/6787)
* Enhancement - Update linkshare capabilities: [#3579](https://github.com/owncloud/ocis/pull/3579)
@@ -64,6 +65,13 @@ The following sections list the changes for unreleased.
https://github.com/owncloud/ocis/pull/3551
* Change - Reduce drives in graph /me/drives API: [#3629](https://github.com/owncloud/ocis/pull/3629)
Reduced the drives in the graph `/me/drives` API to only the drives the user has access to. The
endpoint `/drives` will list all drives when the user has the permission.
https://github.com/owncloud/ocis/pull/3629
* Change - Switched default configuration to use libregraph/idm: [#3331](https://github.com/owncloud/ocis/pull/3331)
We switched the default configuration of oCIS to use the "idm" service (based on
@@ -101,6 +109,7 @@ The following sections list the changes for unreleased.
https://github.com/owncloud/ocis/pull/3601
https://github.com/owncloud/ocis/pull/3605
https://github.com/owncloud/ocis/pull/3611
https://github.com/owncloud/ocis/pull/3621
# Changelog for [1.20.0] (2022-04-13)
The following sections list the changes for 1.20.0.
+6
View File
@@ -0,0 +1,6 @@
Change: Reduce drives in graph /me/drives API
Reduced the drives in the graph `/me/drives` API to only the drives the user has access to.
The endpoint `/drives` will list all drives when the user has the permission.
https://github.com/owncloud/ocis/pull/3629
+1
View File
@@ -10,3 +10,4 @@ https://github.com/owncloud/ocis/pull/3601
https://github.com/owncloud/ocis/pull/3602
https://github.com/owncloud/ocis/pull/3605
https://github.com/owncloud/ocis/pull/3611
https://github.com/owncloud/ocis/pull/3621
+13 -13
View File
@@ -297,8 +297,8 @@ var testCases = []struct {
}, {
Alias: "File created",
SystemEvent: events.FileUploaded{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileCreated{}
@@ -312,8 +312,8 @@ var testCases = []struct {
}, {
Alias: "File read",
SystemEvent: events.FileDownloaded{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileRead{}
@@ -327,8 +327,8 @@ var testCases = []struct {
}, {
Alias: "File trashed",
SystemEvent: events.ItemTrashed{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileDeleted{}
@@ -342,7 +342,7 @@ var testCases = []struct {
}, {
Alias: "File renamed",
SystemEvent: events.ItemMoved{
FileID: reference("sto-123", "iid-123", "./item"),
Ref: reference("sto-123", "iid-123", "./item"),
OldReference: reference("sto-123", "iid-123", "./anotheritem"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
@@ -361,8 +361,8 @@ var testCases = []struct {
}, {
Alias: "File purged",
SystemEvent: events.ItemPurged{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFilePurged{}
@@ -376,7 +376,7 @@ var testCases = []struct {
}, {
Alias: "File restored",
SystemEvent: events.ItemRestored{
FileID: reference("sto-123", "iid-123", "./item"),
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
OldReference: reference("sto-123", "sto-123!iid-123/item", "./oldpath"),
Key: "",
@@ -396,9 +396,9 @@ var testCases = []struct {
}, {
Alias: "File version restored",
SystemEvent: events.FileVersionRestored{
FileID: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Key: "v1",
Ref: reference("sto-123", "iid-123", "./item"),
Owner: userID("uid-123"), // NOTE: owner not yet implemented in reva
Key: "v1",
},
CheckAuditEvent: func(t *testing.T, b []byte) {
ev := types.AuditEventFileVersionRestored{}
+7 -7
View File
@@ -234,7 +234,7 @@ func FilesAuditEvent(base AuditEvent, itemid, owner, path string) AuditEventFile
// FileUploaded converts a FileUploaded event to an AuditEventFileCreated
func FileUploaded(ev events.FileUploaded) AuditEventFileCreated {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
base := BasicAuditEvent(uid, "", MessageFileCreated(iid), ActionFileCreated)
return AuditEventFileCreated{
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
@@ -243,7 +243,7 @@ func FileUploaded(ev events.FileUploaded) AuditEventFileCreated {
// FileDownloaded converts a FileDownloaded event to an AuditEventFileRead
func FileDownloaded(ev events.FileDownloaded) AuditEventFileRead {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
base := BasicAuditEvent(uid, "", MessageFileRead(iid), ActionFileRead)
return AuditEventFileRead{
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
@@ -252,7 +252,7 @@ func FileDownloaded(ev events.FileDownloaded) AuditEventFileRead {
// ItemMoved converts a ItemMoved event to an AuditEventFileRenamed
func ItemMoved(ev events.ItemMoved) AuditEventFileRenamed {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
oldpath := ""
if ev.OldReference != nil {
@@ -268,7 +268,7 @@ func ItemMoved(ev events.ItemMoved) AuditEventFileRenamed {
// ItemTrashed converts a ItemTrashed event to an AuditEventFileDeleted
func ItemTrashed(ev events.ItemTrashed) AuditEventFileDeleted {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
base := BasicAuditEvent(uid, "", MessageFileTrashed(iid), ActionFileTrashed)
return AuditEventFileDeleted{
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
@@ -277,7 +277,7 @@ func ItemTrashed(ev events.ItemTrashed) AuditEventFileDeleted {
// ItemPurged converts a ItemPurged event to an AuditEventFilePurged
func ItemPurged(ev events.ItemPurged) AuditEventFilePurged {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
base := BasicAuditEvent(uid, "", MessageFilePurged(iid), ActionFilePurged)
return AuditEventFilePurged{
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
@@ -286,7 +286,7 @@ func ItemPurged(ev events.ItemPurged) AuditEventFilePurged {
// ItemRestored converts a ItemRestored event to an AuditEventFileRestored
func ItemRestored(ev events.ItemRestored) AuditEventFileRestored {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
oldpath := ""
if ev.OldReference != nil {
@@ -302,7 +302,7 @@ func ItemRestored(ev events.ItemRestored) AuditEventFileRestored {
// FileVersionRestored converts a FileVersionRestored event to an AuditEventFileVersionRestored
func FileVersionRestored(ev events.FileVersionRestored) AuditEventFileVersionRestored {
iid, path, uid := extractFileDetails(ev.FileID, ev.Owner)
iid, path, uid := extractFileDetails(ev.Ref, ev.Owner)
base := BasicAuditEvent(uid, "", MessageFileVersionRestored(iid, ev.Key), ActionFileVersionRestored)
return AuditEventFileVersionRestored{
AuditEventFiles: FilesAuditEvent(base, iid, uid, path),
+44 -14
View File
@@ -31,8 +31,19 @@ import (
merrors "go-micro.dev/v4/errors"
)
// GetDrives implements the Service interface.
// GetDrives lists all drives the current user has access to
func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
g.getDrives(w, r, false)
}
// GetAllDrives lists all drives, including other user's drives, if the current
// user has the permission.
func (g Graph) GetAllDrives(w http.ResponseWriter, r *http.Request) {
g.getDrives(w, r, true)
}
// getDrives implements the Service interface.
func (g Graph) getDrives(w http.ResponseWriter, r *http.Request, unrestricted bool) {
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
// Parse the request with odata parser
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
@@ -41,7 +52,10 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
return
}
g.logger.Info().Interface("query", r.URL.Query()).Msg("Calling GetDrives")
g.logger.Debug().
Interface("query", r.URL.Query()).
Bool("unrestricted", unrestricted).
Msg("Calling getDrives")
ctx := r.Context()
filters, err := generateCs3Filters(odataReq)
@@ -50,7 +64,7 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
errorcode.NotSupported.Render(w, r, http.StatusNotImplemented, err.Error())
return
}
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
res, err := g.ListStorageSpacesWithFilters(ctx, filters, unrestricted)
switch {
case err != nil:
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
@@ -106,7 +120,7 @@ func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
filters := []*storageprovider.ListStorageSpacesRequest_Filter{listStorageSpacesIDFilter(driveID)}
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
res, err := g.ListStorageSpacesWithFilters(ctx, filters, true)
switch {
case err != nil:
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
@@ -273,7 +287,8 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
identifierParts := strings.Split(driveID, "!")
switch len(identifierParts) {
case 1:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[0]
sID, _ := resourceid.StorageIDUnwrap(identifierParts[0])
root.StorageId, root.OpaqueId = identifierParts[0], sID
case 2:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[1]
default:
@@ -398,7 +413,7 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces
}
// ListStorageSpacesWithFilters List Storage Spaces using filters
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter) (*storageprovider.ListStorageSpacesResponse, error) {
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter, unrestricted bool) (*storageprovider.ListStorageSpacesResponse, error) {
client := g.GetGatewayClient()
permissions := make(map[string]struct{}, 1)
@@ -423,17 +438,35 @@ func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*stor
Decoder: "json",
Value: value,
},
"unrestricted": {
Decoder: "plain",
Value: []byte(strconv.FormatBool(unrestricted)),
},
}},
Filters: filters,
})
return res, err
}
func generateSpaceId(id *storageprovider.ResourceId) (spaceID string) {
spaceID = id.GetStorageId()
// 2nd ID to compare is the opaque ID of the Space Root
spaceID2 := id.GetOpaqueId()
if strings.Contains(spaceID, "$") {
spaceID2, _ = resourceid.StorageIDUnwrap(spaceID)
}
// Append opaqueID only if it is different from the spaceID2
if id.OpaqueId != spaceID2 {
spaceID += "!" + id.OpaqueId
}
return spaceID
}
func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
if space.Root == nil {
return nil, fmt.Errorf("space has no root")
}
rootID := resourceid.OwnCloudResourceIDWrap(space.Root)
spaceID := generateSpaceId(space.Root)
var permissions []libregraph.Permission
if space.Opaque != nil {
@@ -491,18 +524,14 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
}
}
spaceID := space.Root.StorageId
if space.Root.OpaqueId != space.Root.StorageId {
spaceID = rootID
}
drive := &libregraph.Drive{
Id: &spaceID,
Id: libregraph.PtrString(spaceID),
Name: &space.Name,
//"createdDateTime": "string (timestamp)", // TODO read from StorageSpace ... needs Opaque for now
//"description": "string", // TODO read from StorageSpace ... needs Opaque for now
DriveType: &space.SpaceType,
Root: &libregraph.DriveItem{
Id: &rootID,
Id: libregraph.PtrString(resourceid.OwnCloudResourceIDWrap(space.Root)),
Permissions: permissions,
},
}
@@ -735,9 +764,10 @@ func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
root := &storageprovider.ResourceId{}
identifierParts := strings.Split(driveID, "!")
sID, _ := resourceid.StorageIDUnwrap(identifierParts[0])
switch len(identifierParts) {
case 1:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[0]
root.StorageId, root.OpaqueId = identifierParts[0], sID
case 2:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[1]
default:
@@ -201,7 +201,7 @@ var _ = Describe("Graph", func() {
Id: &provider.StorageSpaceId{OpaqueId: "aID!differentID"},
SpaceType: "mountpoint",
Root: &provider.ResourceId{
StorageId: "aID",
StorageId: "prID$aID",
OpaqueId: "differentID",
},
Name: "New Folder",
@@ -246,11 +246,11 @@ var _ = Describe("Graph", func() {
value := response["value"][0]
Expect(*value.DriveAlias).To(Equal("mountpoint/new-folder"))
Expect(*value.DriveType).To(Equal("mountpoint"))
Expect(*value.Id).To(Equal("aID!differentID"))
Expect(*value.Id).To(Equal("prID$aID!differentID"))
Expect(*value.Name).To(Equal("New Folder"))
Expect(*value.Root.WebDavUrl).To(Equal("https://localhost:9200/dav/spaces/aID!differentID"))
Expect(*value.Root.WebDavUrl).To(Equal("https://localhost:9200/dav/spaces/prID$aID!differentID"))
Expect(*value.Root.ETag).To(Equal("101112131415"))
Expect(*value.Root.Id).To(Equal("aID!differentID"))
Expect(*value.Root.Id).To(Equal("prID$aID!differentID"))
Expect(*value.Root.RemoteItem.ETag).To(Equal("123456789"))
Expect(*value.Root.RemoteItem.Id).To(Equal("ownerStorageID!opaqueID"))
Expect(value.Root.RemoteItem.LastModifiedDateTime.UTC()).To(Equal(time.Unix(1648327606, 0).UTC()))
+1 -1
View File
@@ -173,7 +173,7 @@ func NewService(opts ...Option) Service {
account.JWTSecret(options.Config.TokenManager.JWTSecret)),
)
r.Route("/drives", func(r chi.Router) {
r.Get("/", svc.GetDrives)
r.Get("/", svc.GetAllDrives)
r.Post("/", svc.CreateDrive)
r.Route("/{driveID}", func(r chi.Router) {
r.Patch("/", svc.UpdateDrive)
+1 -1
View File
@@ -9,7 +9,7 @@ require (
github.com/blevesearch/bleve/v2 v2.3.2
github.com/coreos/go-oidc/v3 v3.1.0
github.com/cs3org/go-cs3apis v0.0.0-20220412090512-93c5918b4bde
github.com/cs3org/reva/v2 v2.0.0-20220427203355-0164880ac7d3
github.com/cs3org/reva/v2 v2.0.0-20220502075009-8bcec2e4663e
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
+2 -2
View File
@@ -318,8 +318,8 @@ github.com/cs3org/go-cs3apis v0.0.0-20220412090512-93c5918b4bde h1:WrD9O8ZaWvsm0
github.com/cs3org/go-cs3apis v0.0.0-20220412090512-93c5918b4bde/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/reva v1.18.0 h1:MbPS5ZAa8RzKcTxAVeSDdISB3XXqLIxqB03BTN5ReBY=
github.com/cs3org/reva v1.18.0/go.mod h1:e5VDUDu4vVWIeVkZcW//n6UZzhGGMa+Tz/whCiX3N6o=
github.com/cs3org/reva/v2 v2.0.0-20220427203355-0164880ac7d3 h1:6sKjGI0AUW5tBXWBduaBoc+9sNYZWQR894G0oFCbus0=
github.com/cs3org/reva/v2 v2.0.0-20220427203355-0164880ac7d3/go.mod h1:2e/4HcIy54Mic3V7Ow0bz4n5dkZU0dHIZSWomFe5vng=
github.com/cs3org/reva/v2 v2.0.0-20220502075009-8bcec2e4663e h1:ym80MMvfFLHMxt6aiU67kTe/pzRBaSOUNdPkmeKYejk=
github.com/cs3org/reva/v2 v2.0.0-20220502075009-8bcec2e4663e/go.mod h1:2e/4HcIy54Mic3V7Ow0bz4n5dkZU0dHIZSWomFe5vng=
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=
@@ -1847,10 +1847,6 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
#### [OCS status code zero](https://github.com/owncloud/ocis/issues/3621)
- [apiShareManagementToShares/moveReceivedShare.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/moveReceivedShare.feature#L32)
#### [share_with_user_type is not set in response](https://github.com/owncloud/ocis/issues/3622)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:37](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L37)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:38](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L38)
#### [HTTP status code differ while listing the contents of another user's trash bin](https://github.com/owncloud/ocis/issues/3561)
- [apiTrashbin/trashbinFilesFolders.feature:199](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiTrashbin/trashbinFilesFolders.feature#L199)
- [apiTrashbin/trashbinFilesFolders.feature:223](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiTrashbin/trashbinFilesFolders.feature#L223)
@@ -1639,10 +1639,6 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
#### [OCS status code zero](https://github.com/owncloud/ocis/issues/3621)
- [apiShareManagementToShares/moveReceivedShare.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/moveReceivedShare.feature#L32)
#### [share_with_user_type is not set in response](https://github.com/owncloud/ocis/issues/3622)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:37](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L37)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:38](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L38)
#### [HTTP status code differ while listing the contents of another user's trash bin](https://github.com/owncloud/ocis/issues/3561)
- [apiTrashbin/trashbinFilesFolders.feature:199](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiTrashbin/trashbinFilesFolders.feature#L199)
- [apiTrashbin/trashbinFilesFolders.feature:223](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiTrashbin/trashbinFilesFolders.feature#L223)
@@ -220,6 +220,24 @@ class SpacesContext implements Context {
return $spaces[$spaceName];
}
/**
* The method finds available spaces to the manager user and returns the space by spaceName
*
* @param string $user
* @param string $spaceName
*
* @return array
*/
public function getSpaceByNameManager(string $user, string $spaceName): array {
$this->theUserListsAllAvailableSpacesUsingTheGraphApi($user);
$spaces = $this->getAvailableSpaces();
Assert::assertIsArray($spaces[$spaceName], "Space with name $spaceName for user $user not found");
Assert::assertNotEmpty($spaces[$spaceName]["root"]["webDavUrl"], "WebDavUrl for space with name $spaceName for user $user not found");
return $spaces[$spaceName];
}
/**
* The method finds file by fileName and spaceName and returns data of file wich contains in responseHeader
* fileName contains the path, if the file is in the folder
@@ -349,7 +367,7 @@ class SpacesContext implements Context {
/**
* The method first disables and then deletes spaces
* @param string $driveType
*
*
* @return void
*
* @throws Exception
@@ -410,6 +428,33 @@ class SpacesContext implements Context {
return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body);
}
/**
* Send Graph List All Spaces 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 listAllSpacesRequest(
string $user,
string $password,
string $urlArguments = '',
string $xRequestId = '',
array $body = [],
array $headers = []
): ResponseInterface {
$fullUrl = $this->baseUrl . "/graph/v1.0/drives/" . $urlArguments;
return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body);
}
/**
* Send Graph List Single Space Request
*
@@ -530,6 +575,24 @@ class SpacesContext implements Context {
$this->rememberTheAvailableSpaces();
}
/**
*
* @param string $user
*
* @return void
*
* @throws GuzzleException
*/
public function theUserListsAllAvailableSpacesUsingTheGraphApi(string $user): void {
$this->featureContext->setResponse(
$this->listAllSpacesRequest(
$user,
$this->featureContext->getPasswordForUser($user)
)
);
$this->rememberTheAvailableSpaces();
}
/**
* @When /^user "([^"]*)" lists all available spaces via the GraphApi with query "([^"]*)"$/
*
@@ -1145,7 +1208,7 @@ class SpacesContext implements Context {
$results = [];
if ($multistatusResults !== null) {
foreach ($multistatusResults as $multistatusResult) {
$entryPath = $multistatusResult['value'][0]['value'];
$entryPath = \urldecode($multistatusResult['value'][0]['value']);
$entryName = \str_replace($topWebDavPath, "", $entryPath);
$entryName = \rawurldecode($entryName);
$entryName = \trim($entryName, "/");
@@ -1951,7 +2014,7 @@ class SpacesContext implements Context {
string $userWithManagerRights = ''
): void {
if (!empty($userWithManagerRights)) {
$space = $this->getSpaceByName($userWithManagerRights, $spaceName);
$space = $this->getSpaceByNameManager($userWithManagerRights, $spaceName);
} else {
$space = $this->getSpaceByName($user, $spaceName);
}