tests: check access of guests and sharees outside of the shared resource

This commit is contained in:
v.scharf committed 2026-10-20 16:59:01 +02:00
1 parent 208f1e8b33
commit d5ca07e11f
9 files changed
+882 -112

No files matched your search

+252 -2
View File
@@ -21,6 +21,7 @@
use Behat\Behat\Context\Context;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\Step\Given;
use Behat\Step\Then;
use Behat\Step\When;
@@ -552,7 +553,7 @@ class GuestLinkContext implements Context {
null,
'MOVE',
$path,
\array_merge($this->getSessionHeaders($guest), ['Destination' => $this->featureContext->getBaseUrl() . '/' . WebDavHelper::getDavPath(WebDavHelper::DAV_VERSION_SPACES, $folderId) . '/' . $newName]),
\array_merge($this->getSessionHeaders($guest), ['Destination' => $this->getDavUrl($folderId, $newName)]),
$folderId,
$this->featureContext->getStepLineRef(),
null,
@@ -590,7 +591,7 @@ class GuestLinkContext implements Context {
null,
'MOVE',
$path,
\array_merge($this->getSessionHeaders($guest), ['Destination' => $this->featureContext->getBaseUrl() . '/' . WebDavHelper::getDavPath(WebDavHelper::DAV_VERSION_SPACES, $spaceRootId) . '/' . $destination]),
\array_merge($this->getSessionHeaders($guest), ['Destination' => $this->getDavUrl($spaceRootId, $destination)]),
$folderId,
$this->featureContext->getStepLineRef(),
null,
@@ -599,6 +600,255 @@ class GuestLinkContext implements Context {
);
}
/**
* @param string $id
* @param string $name
*
* @return string the WebDAV URL of a resource inside the resource with the given id
*/
private function getDavUrl(string $id, string $name): string {
return $this->featureContext->getBaseUrl() . '/' . WebDavHelper::getDavPath(WebDavHelper::DAV_VERSION_SPACES, $id) . '/' . $name;
}
/**
* @param string $guest
* @param string $method COPY or MOVE
* @param string $path
* @param string $folderId
* @param string $destinationFolderId
*
* @return void
* @throws GuzzleException
*/
private function copyOrMoveIntoFolder(
string $guest,
string $method,
string $path,
string $folderId,
string $destinationFolderId
): void {
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
null,
null,
$method,
$path,
\array_merge($this->getSessionHeaders($guest), ['Destination' => $this->getDavUrl($destinationFolderId, \basename($path))]),
$folderId,
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $guest
* @param string $path
* @param string $folder
* @param string $space
* @param string $owner
* @param string $destinationFolder
* @param string $destinationSpace
* @param string $destinationOwner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest copies :path inside folder :folder of space :space of user :owner to folder :destinationFolder of space :destinationSpace of user :destinationOwner using the WebDAV API')]
public function guestCopiesIntoFolder(
string $guest,
string $path,
string $folder,
string $space,
string $owner,
string $destinationFolder,
string $destinationSpace,
string $destinationOwner
): void {
$this->copyOrMoveIntoFolder(
$guest,
'COPY',
$path,
$this->spacesContext->getResourceId($owner, $space, $folder),
$this->spacesContext->getResourceId($destinationOwner, $destinationSpace, $destinationFolder)
);
}
/**
* @param string $guest
* @param string $path
* @param string $folder
* @param string $space
* @param string $owner
* @param string $destinationFolder
* @param string $destinationSpace
* @param string $destinationOwner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest moves :path inside folder :folder of space :space of user :owner to folder :destinationFolder of space :destinationSpace of user :destinationOwner using the WebDAV API')]
public function guestMovesIntoFolder(
string $guest,
string $path,
string $folder,
string $space,
string $owner,
string $destinationFolder,
string $destinationSpace,
string $destinationOwner
): void {
$this->copyOrMoveIntoFolder(
$guest,
'MOVE',
$path,
$this->spacesContext->getResourceId($owner, $space, $folder),
$this->spacesContext->getResourceId($destinationOwner, $destinationSpace, $destinationFolder)
);
}
/**
* @param string $guest
* @param string $path
* @param string $folder
* @param string $space
* @param string $owner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest deletes :path inside folder :folder of space :space of user :owner using the WebDAV API')]
public function guestDeletesInsideFolder(string $guest, string $path, string $folder, string $space, string $owner): void {
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
null,
null,
'DELETE',
$path,
$this->getSessionHeaders($guest),
$this->spacesContext->getResourceId($owner, $space, $folder),
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $guest
* @param string $folder
* @param string $space
* @param string $owner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest tries to delete the shared folder :folder of space :space of user :owner using the WebDAV API')]
public function guestTriesToDeleteTheSharedFolder(string $guest, string $folder, string $space, string $owner): void {
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
null,
null,
'DELETE',
'',
$this->getSessionHeaders($guest),
$this->spacesContext->getResourceId($owner, $space, $folder),
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $guest
* @param string $folder
* @param string $space
* @param string $owner
* @param string $newName
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest tries to rename the shared folder :folder of space :space of user :owner to :newName using the WebDAV API')]
public function guestTriesToRenameTheSharedFolder(
string $guest,
string $folder,
string $space,
string $owner,
string $newName
): void {
$spaceRootId = $this->spacesContext->getResourceId($owner, $space, '');
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
null,
null,
'MOVE',
'',
\array_merge($this->getSessionHeaders($guest), ['Destination' => $this->getDavUrl($spaceRootId, $newName)]),
$this->spacesContext->getResourceId($owner, $space, $folder),
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $guest
* @param TableNode $resources with the columns resource, space and owner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest downloads the archive of these resources using the archiver:')]
public function guestDownloadsTheArchiveOfTheseResources(string $guest, TableNode $resources): void {
$this->featureContext->verifyTableNodeColumns($resources, ['resource', 'space', 'owner']);
$ids = [];
foreach ($resources->getHash() as $row) {
$ids[] = 'id=' . \rawurlencode($this->spacesContext->getResourceId($row['owner'], $row['space'], $row['resource']));
}
$this->downloadArchive($guest, $ids);
}
/**
* @param string $guest
* @param string $space
* @param string $owner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest downloads the archive of space :space of user :owner using the archiver')]
public function guestDownloadsTheArchiveOfSpace(string $guest, string $space, string $owner): void {
$this->downloadArchive($guest, ['id=' . \rawurlencode($this->spacesContext->getSpaceIdByName($owner, $space))]);
}
/**
* @param string $guest
* @param string[] $query
*
* @return void
* @throws GuzzleException
*/
private function downloadArchive(string $guest, array $query): void {
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$this->featureContext->getBaseUrl() . '/archiver?' . \implode('&', $query),
$this->featureContext->getStepLineRef(),
'GET',
null,
null,
$this->getSessionHeaders($guest),
)
);
}
/**
* @param string $guest
* @param string $method
@@ -4675,4 +4675,250 @@ class SpacesContext implements Context {
$schema
);
}
/**
* Sends a WebDAV request to the space of the owner of a received share,
* using the drive id that the sharee gets from the sharedWithMe list
*
* @param string $user
* @param string $method
* @param string $share
* @param string $path
* @param array $headers
* @param string|null $body
*
* @return void
* @throws GuzzleException
*/
private function sendRequestToSpaceOfShareOwner(
string $user,
string $method,
string $share,
string $path,
array $headers = [],
?string $body = null
): void {
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
$this->featureContext->getActualUsername($user),
$this->featureContext->getPasswordForUser($user),
$method,
$path,
$headers,
$this->getSharesRemoteItemParentDriveId($user, $share),
$this->featureContext->getStepLineRef(),
$body,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $user
* @param string $share
*
* @return void
* @throws GuzzleException
*/
#[When('user :user lists the content of the space of the owner of share :share using the WebDAV API')]
public function userListsTheContentOfTheSpaceOfTheOwnerOfShare(string $user, string $share): void {
$this->sendRequestToSpaceOfShareOwner($user, 'PROPFIND', $share, '', ['Depth' => '1']);
}
/**
* @param string $user
* @param string $file
* @param string $share
*
* @return void
* @throws GuzzleException
*/
#[When('user :user downloads file :file from the space of the owner of share :share using the WebDAV API')]
public function userDownloadsFileFromTheSpaceOfTheOwnerOfShare(string $user, string $file, string $share): void {
$this->sendRequestToSpaceOfShareOwner($user, 'GET', $share, $file);
}
/**
* @param string $user
* @param string $content
* @param string $file
* @param string $share
*
* @return void
* @throws GuzzleException
*/
#[When('user :user uploads content :content to file :file in the space of the owner of share :share using the WebDAV API')]
public function userUploadsContentToFileInTheSpaceOfTheOwnerOfShare(
string $user,
string $content,
string $file,
string $share
): void {
$this->sendRequestToSpaceOfShareOwner($user, 'PUT', $share, $file, [], $content);
}
/**
* @param string $user
* @param string $folder
* @param string $share
*
* @return void
* @throws GuzzleException
*/
#[When('user :user creates folder :folder in the space of the owner of share :share using the WebDAV API')]
public function userCreatesFolderInTheSpaceOfTheOwnerOfShare(string $user, string $folder, string $share): void {
$this->sendRequestToSpaceOfShareOwner($user, 'MKCOL', $share, $folder);
}
/**
* @param string $user
* @param string $file
* @param string $share
*
* @return void
* @throws GuzzleException
*/
#[When('user :user deletes file :file from the space of the owner of share :share using the WebDAV API')]
public function userDeletesFileFromTheSpaceOfTheOwnerOfShare(string $user, string $file, string $share): void {
$this->sendRequestToSpaceOfShareOwner($user, 'DELETE', $share, $file);
}
/**
* @param string $user
* @param string $method COPY or MOVE
* @param string $file
* @param string $share
* @param string $destination
*
* @return void
* @throws GuzzleException
*/
private function copyOrMoveOutOfShareToSpaceOfShareOwner(
string $user,
string $method,
string $file,
string $share,
string $destination
): void {
$driveId = $this->getSharesRemoteItemParentDriveId($user, $share);
$destinationUrl = $this->featureContext->getBaseUrl() . '/'
. WebDavHelper::getDavPath(WebDavHelper::DAV_VERSION_SPACES, $driveId) . '/' . $destination;
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
$this->featureContext->getActualUsername($user),
$this->featureContext->getPasswordForUser($user),
$method,
$file,
['Destination' => $destinationUrl],
$this->getSharesRemoteItemId($user, $share),
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $user
* @param string $file
* @param string $share
* @param string $destination
*
* @return void
* @throws GuzzleException
*/
#[When('user :user tries to copy file :file from share :share to :destination in the space of the owner using the WebDAV API')]
public function userTriesToCopyFileFromShareToTheSpaceOfTheOwner(
string $user,
string $file,
string $share,
string $destination
): void {
$this->copyOrMoveOutOfShareToSpaceOfShareOwner($user, 'COPY', $file, $share, $destination);
}
/**
* @param string $user
* @param string $file
* @param string $share
* @param string $destination
*
* @return void
* @throws GuzzleException
*/
#[When('user :user tries to move file :file from share :share to :destination in the space of the owner using the WebDAV API')]
public function userTriesToMoveFileFromShareToTheSpaceOfTheOwner(
string $user,
string $file,
string $share,
string $destination
): void {
$this->copyOrMoveOutOfShareToSpaceOfShareOwner($user, 'MOVE', $file, $share, $destination);
}
/**
* @param string $user
* @param string $file
* @param string $share
* @param string $destination
* @param string $destinationShare
*
* @return void
* @throws GuzzleException
*/
#[When('user :user moves file :file from share :share to :destination in share :destinationShare using the WebDAV API')]
public function userMovesFileFromShareToShare(
string $user,
string $file,
string $share,
string $destination,
string $destinationShare
): void {
$destinationUrl = $this->featureContext->getBaseUrl() . '/'
. WebDavHelper::getDavPath(
WebDavHelper::DAV_VERSION_SPACES,
$this->getSharesRemoteItemId($user, $destinationShare)
) . '/' . $destination;
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
$this->featureContext->getActualUsername($user),
$this->featureContext->getPasswordForUser($user),
'MOVE',
$file,
['Destination' => $destinationUrl],
$this->getSharesRemoteItemId($user, $share),
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
/**
* @param string $user
* @param string $share
*
* @return void
* @throws GuzzleException
*/
#[When('user :user tries to delete the shared folder :share using the WebDAV API')]
public function userTriesToDeleteTheSharedFolder(string $user, string $share): void {
$this->featureContext->setResponse(
WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
$this->featureContext->getActualUsername($user),
$this->featureContext->getPasswordForUser($user),
'DELETE',
'',
[],
$this->getSharesRemoteItemId($user, $share),
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
)
);
}
}
@@ -151,7 +151,17 @@
#### [sharee (editor role) MOVE a file by file-id into shared sub-folder returns 502](https://github.com/owncloud/ocis/issues/7617)
- [apiSpacesDavOperation/moveByFileId.feature:368](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L368)
- [apiSpacesDavOperation/moveByFileId.feature:591](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L591)
- [apiSpacesDavOperation/moveByFileId.feature:620](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L620)
#### [MOVE between spaces returns 502 but deletes the existing destination file](https://github.com/opencloud-eu/opencloud/issues/3767)
- [apiGuestLink/guestLinkFileOperations.feature:242](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiGuestLink/guestLinkFileOperations.feature#L242)
- [apiSpacesDavOperation/moveByFileId.feature:471](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L471)
#### [Sharee with the Editor role can delete the shared folder of the owner using file-id](https://github.com/opencloud-eu/opencloud/issues/3770)
- [apiGuestLink/guestLinkFileOperations.feature:110](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiGuestLink/guestLinkFileOperations.feature#L110)
- [apiSpacesDavOperation/deleteByFileId.feature:14](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/deleteByFileId.feature#L14)
#### [MOVE a file into same folder with same name returns 404 instead of 403](https://github.com/owncloud/ocis/issues/1976)
@@ -151,7 +151,17 @@
#### [sharee (editor role) MOVE a file by file-id into shared sub-folder returns 502](https://github.com/owncloud/ocis/issues/7617)
- [apiSpacesDavOperation/moveByFileId.feature:368](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L368)
- [apiSpacesDavOperation/moveByFileId.feature:591](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L591)
- [apiSpacesDavOperation/moveByFileId.feature:620](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L620)
#### [MOVE between spaces returns 502 but deletes the existing destination file](https://github.com/opencloud-eu/opencloud/issues/3767)
- [apiGuestLink/guestLinkFileOperations.feature:242](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiGuestLink/guestLinkFileOperations.feature#L242)
- [apiSpacesDavOperation/moveByFileId.feature:471](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/moveByFileId.feature#L471)
#### [Sharee with the Editor role can delete the shared folder of the owner using file-id](https://github.com/opencloud-eu/opencloud/issues/3770)
- [apiGuestLink/guestLinkFileOperations.feature:110](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiGuestLink/guestLinkFileOperations.feature#L110)
- [apiSpacesDavOperation/deleteByFileId.feature:14](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiSpacesDavOperation/deleteByFileId.feature#L14)
#### [MOVE a file into same folder with same name returns 404 instead of 403](https://github.com/owncloud/ocis/issues/1976)
@@ -0,0 +1,256 @@
@email
Feature: file operations of a guest on shared resources
As a guest
I want to work with the resources shared with me
So that I can collaborate without an account, while the rest of the owner's files stay private
Background:
Given user "Alice" has been created with default attributes
And user "Alice" has created folder "folderToShare"
And user "Alice" has uploaded file with content "inside" to "folderToShare/inside.txt"
And user "Alice" has sent the following resource share invitation:
| resource | folderToShare |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Editor |
And guest "guest@example.org" has verified the guest link from the last email
Scenario: guest works inside the shared folder
When guest "guest@example.org" lists the content of folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "207"
When guest "guest@example.org" uploads content "uploaded by guest" to "new.txt" inside folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" creates folder "newFolder" inside folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" renames "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to "renamed.txt" using the WebDAV API
Then the HTTP status code should be "201"
And for user "Alice" the content of the file "folderToShare/new.txt" of the space "Personal" should be "uploaded by guest"
And as "Alice" folder "folderToShare/newFolder" should exist
And as "Alice" file "folderToShare/renamed.txt" should exist
And as "Alice" file "folderToShare/inside.txt" should not exist
Scenario: guest cannot move a file out of the shared folder
When guest "guest@example.org" tries to move "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to "stolen.txt" in the root of that space using the WebDAV API
Then the HTTP status code should be "409"
And as "Alice" file "folderToShare/inside.txt" should exist
And as "Alice" file "stolen.txt" should not exist
Scenario: guest session gives access to all shares of the same guest
Given user "Brian" has been created with default attributes
And user "Alice" has uploaded file with content "from Alice" to "aliceFile.txt"
And user "Brian" has uploaded file with content "from Brian" to "brianFile.txt"
And user "Alice" has sent the following resource share invitation:
| resource | aliceFile.txt |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
And user "Brian" has sent the following resource share invitation:
| resource | brianFile.txt |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
When guest "guest@example.org" downloads file "aliceFile.txt" shared from space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "from Alice"
When guest "guest@example.org" downloads file "brianFile.txt" shared from space "Personal" of user "Brian" using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "from Brian"
When guest "guest@example.org" uploads content "changed by guest" to file "aliceFile.txt" shared from space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
When guest "guest@example.org" lists the shares shared with them using the Graph API
Then the HTTP status code should be "200"
And the JSON data of the response should match
"""
{
"type": "object",
"required": ["value"],
"properties": {
"value": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"uniqueItems": true,
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "enum": ["folderToShare", "aliceFile.txt", "brianFile.txt"] }
}
}
}
}
}
"""
Scenario Outline: guest cannot manage the share
When guest "guest@example.org" sends HTTP method "<method>" to the Graph endpoint "<endpoint>" of resource "folderToShare" of space "Personal" of user "Alice"
Then the HTTP status code should be "401"
Examples:
| method | endpoint |
| GET | permissions |
| POST | invite |
| POST | createLink |
Scenario: guest session with an invalid signature is rejected
Given the signature of the guest session of guest "guest@example.org" has been changed
When guest "guest@example.org" lists the shares shared with them using the Graph API
Then the HTTP status code should be "401"
When guest "guest@example.org" lists the content of folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "401"
@issue-3770
Scenario: guest with the Editor role cannot delete the shared folder
When guest "guest@example.org" tries to delete the shared folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
And as "Alice" folder "folderToShare" should exist
And as "Alice" file "folderToShare/inside.txt" should exist
Scenario: guest cannot rename the shared folder
When guest "guest@example.org" tries to rename the shared folder "folderToShare" of space "Personal" of user "Alice" to "renamedFolder" using the WebDAV API
Then the HTTP status code should be "409"
And as "Alice" folder "folderToShare" should exist
And as "Alice" folder "renamedFolder" should not exist
Scenario: guest with the Viewer role cannot change the shared folder
Given user "Alice" has created folder "viewerFolder"
And user "Alice" has uploaded file with content "viewer" to "viewerFolder/viewer.txt"
And user "Alice" has sent the following resource share invitation:
| resource | viewerFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
When guest "guest@example.org" uploads content "uploaded by guest" to "new.txt" inside folder "viewerFolder" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
When guest "guest@example.org" creates folder "newFolder" inside folder "viewerFolder" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
When guest "guest@example.org" renames "viewer.txt" inside folder "viewerFolder" of space "Personal" of user "Alice" to "renamed.txt" using the WebDAV API
Then the HTTP status code should be "403"
When guest "guest@example.org" deletes "viewer.txt" inside folder "viewerFolder" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
And as "Alice" file "viewerFolder/viewer.txt" should exist
And as "Alice" file "viewerFolder/new.txt" should not exist
And as "Alice" folder "viewerFolder/newFolder" should not exist
Scenario: guest downloads the archive of the shared folder
Given user "Alice" has uploaded file with content "second" to "folderToShare/second.txt"
And user "Alice" has created folder "folderToShare/subFolder"
And user "Alice" has uploaded file with content "nested" to "folderToShare/subFolder/nested.txt"
When guest "guest@example.org" downloads the archive of these resources using the archiver:
| resource | space | owner |
| folderToShare | Personal | Alice |
Then the HTTP status code should be "200"
And the downloaded zip archive should contain these files:
| name | content |
| folderToShare/inside.txt | inside |
| folderToShare/second.txt | second |
| folderToShare/subFolder/nested.txt | nested |
Scenario: guest downloads the archive of the shared folders of different users
Given user "Brian" has been created with default attributes
And user "Brian" has created folder "brianFolder"
And user "Brian" has uploaded file with content "from Brian" to "brianFolder/brian.txt"
And user "Brian" has sent the following resource share invitation:
| resource | brianFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
When guest "guest@example.org" downloads the archive of these resources using the archiver:
| resource | space | owner |
| folderToShare | Personal | Alice |
| brianFolder | Personal | Brian |
Then the HTTP status code should be "200"
And the downloaded zip archive should contain these files:
| name | content |
| folderToShare/inside.txt | inside |
| brianFolder/brian.txt | from Brian |
Scenario: guest cannot download the archive of resources outside the shared folder
Given user "Alice" has uploaded file with content "private" to "private.txt"
When guest "guest@example.org" downloads the archive of space "Personal" of user "Alice" using the archiver
Then the HTTP status code should be "404"
When guest "guest@example.org" downloads the archive of these resources using the archiver:
| resource | space | owner |
| private.txt | Personal | Alice |
Then the HTTP status code should be "404"
When guest "guest@example.org" downloads the archive of these resources using the archiver:
| resource | space | owner |
| folderToShare | Personal | Alice |
| private.txt | Personal | Alice |
Then the HTTP status code should be "404"
Scenario: guest copies and moves files between the shares of different users
Given user "Brian" has been created with default attributes
And user "Alice" has created folder "editorFolder"
And user "Alice" has created folder "viewerFolder"
And user "Alice" has uploaded file with content "viewer" to "viewerFolder/viewer.txt"
And user "Brian" has created folder "brianFolder"
And user "Alice" has sent the following resource share invitation:
| resource | editorFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Editor |
And user "Alice" has sent the following resource share invitation:
| resource | viewerFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
And user "Brian" has sent the following resource share invitation:
| resource | brianFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Editor |
When guest "guest@example.org" copies "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to folder "editorFolder" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" copies "viewer.txt" inside folder "viewerFolder" of space "Personal" of user "Alice" to folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" copies "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to folder "viewerFolder" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
When guest "guest@example.org" moves "viewer.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to folder "editorFolder" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" moves "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to folder "brianFolder" of space "Personal" of user "Brian" using the WebDAV API
Then the HTTP status code should be "502"
When guest "guest@example.org" copies "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to folder "brianFolder" of space "Personal" of user "Brian" using the WebDAV API
Then the HTTP status code should be "201"
And for user "Alice" the content of the file "editorFolder/inside.txt" of the space "Personal" should be "inside"
And for user "Alice" the content of the file "editorFolder/viewer.txt" of the space "Personal" should be "viewer"
And for user "Brian" the content of the file "brianFolder/inside.txt" of the space "Personal" should be "inside"
And as "Alice" file "folderToShare/inside.txt" should exist
And as "Alice" file "folderToShare/viewer.txt" should not exist
And as "Alice" file "viewerFolder/viewer.txt" should exist
And as "Alice" file "viewerFolder/inside.txt" should not exist
@issue-3767
Scenario: guest moves a file into a share of another user over an existing file
Given user "Brian" has been created with default attributes
And user "Brian" has created folder "brianFolder"
And user "Brian" has uploaded file with content "from Brian" to "brianFolder/inside.txt"
And user "Brian" has sent the following resource share invitation:
| resource | brianFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Editor |
When guest "guest@example.org" moves "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to folder "brianFolder" of space "Personal" of user "Brian" using the WebDAV API
Then the HTTP status code should be "502"
And for user "Brian" the content of the file "brianFolder/inside.txt" of the space "Personal" should be "from Brian"
And for user "Alice" the content of the file "folderToShare/inside.txt" of the space "Personal" should be "inside"
@@ -1,108 +0,0 @@
@email
Feature: guest link access is limited to the shared resource
As a user sharing a folder with a guest
I want the guest to only access the shared folder
So that the rest of my files stay private
Background:
Given user "Alice" has been created with default attributes
And user "Alice" has created folder "folderToShare"
And user "Alice" has uploaded file with content "inside" to "folderToShare/inside.txt"
And user "Alice" has sent the following resource share invitation:
| resource | folderToShare |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Editor |
And guest "guest@example.org" has verified the guest link from the last email
Scenario: guest works inside the shared folder
When guest "guest@example.org" lists the content of folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "207"
When guest "guest@example.org" uploads content "uploaded by guest" to "new.txt" inside folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" creates folder "newFolder" inside folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "201"
When guest "guest@example.org" renames "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to "renamed.txt" using the WebDAV API
Then the HTTP status code should be "201"
And for user "Alice" the content of the file "folderToShare/new.txt" of the space "Personal" should be "uploaded by guest"
And as "Alice" folder "folderToShare/newFolder" should exist
And as "Alice" file "folderToShare/renamed.txt" should exist
And as "Alice" file "folderToShare/inside.txt" should not exist
Scenario: guest cannot move a file out of the shared folder
When guest "guest@example.org" tries to move "inside.txt" inside folder "folderToShare" of space "Personal" of user "Alice" to "stolen.txt" in the root of that space using the WebDAV API
Then the HTTP status code should be "409"
And as "Alice" file "folderToShare/inside.txt" should exist
And as "Alice" file "stolen.txt" should not exist
Scenario: guest session gives access to all shares of the same guest
Given user "Brian" has been created with default attributes
And user "Alice" has uploaded file with content "from Alice" to "aliceFile.txt"
And user "Brian" has uploaded file with content "from Brian" to "brianFile.txt"
And user "Alice" has sent the following resource share invitation:
| resource | aliceFile.txt |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
And user "Brian" has sent the following resource share invitation:
| resource | brianFile.txt |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
When guest "guest@example.org" downloads file "aliceFile.txt" shared from space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "from Alice"
When guest "guest@example.org" downloads file "brianFile.txt" shared from space "Personal" of user "Brian" using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "from Brian"
When guest "guest@example.org" uploads content "changed by guest" to file "aliceFile.txt" shared from space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "403"
When guest "guest@example.org" lists the shares shared with them using the Graph API
Then the HTTP status code should be "200"
And the JSON data of the response should match
"""
{
"type": "object",
"required": ["value"],
"properties": {
"value": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"uniqueItems": true,
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "enum": ["folderToShare", "aliceFile.txt", "brianFile.txt"] }
}
}
}
}
}
"""
Scenario Outline: guest cannot manage the share
When guest "guest@example.org" sends HTTP method "<method>" to the Graph endpoint "<endpoint>" of resource "folderToShare" of space "Personal" of user "Alice"
Then the HTTP status code should be "401"
Examples:
| method | endpoint |
| GET | permissions |
| POST | invite |
| POST | createLink |
Scenario: guest session with an invalid signature is rejected
Given the signature of the guest session of guest "guest@example.org" has been changed
When guest "guest@example.org" lists the shares shared with them using the Graph API
Then the HTTP status code should be "401"
When guest "guest@example.org" lists the content of folder "folderToShare" of space "Personal" of user "Alice" using the WebDAV API
Then the HTTP status code should be "401"
@@ -0,0 +1,28 @@
Feature: deleting resources using file id
As a user
I want to be able to delete resources using file id
So that I can remove unwanted data
Background:
Given using spaces DAV path
And these users have been created with default attributes:
| username |
| Alice |
| Brian |
@issue-3770
Scenario: sharee with the Editor role tries to delete the shared folder using its id
Given user "Alice" has created folder "folderToShare"
And user "Alice" has uploaded file with content "inside" to "folderToShare/inside.txt"
And user "Alice" has sent the following resource share invitation:
| resource | folderToShare |
| space | Personal |
| sharee | Brian |
| shareType | user |
| permissionsRole | Editor |
And user "Brian" has a share "folderToShare" synced
When user "Brian" tries to delete the shared folder "folderToShare" using the WebDAV API
Then the HTTP status code should be "403"
And as "Alice" folder "folderToShare" should exist
And as "Alice" file "folderToShare/inside.txt" should exist
And as "Brian" folder "/Shares/folderToShare" should exist
@@ -467,6 +467,35 @@ Feature: moving/renaming file using file id
| Viewer | Editor |
| Viewer | Viewer |
@issue-3767
Scenario: move a file from a shared folder into a shared folder of another user over an existing file
Given these users have been created with default attributes:
| username |
| Brian |
| Carol |
And user "Alice" has created folder "aliceShare"
And user "Alice" has uploaded file with content "from Alice" to "aliceShare/aliceFile.txt"
And user "Carol" has created folder "carolShare"
And user "Carol" has uploaded file with content "from Carol" to "carolShare/carolFile.txt"
And user "Alice" has sent the following resource share invitation:
| resource | aliceShare |
| space | Personal |
| sharee | Brian |
| shareType | user |
| permissionsRole | Editor |
And user "Brian" has a share "aliceShare" synced
And user "Carol" has sent the following resource share invitation:
| resource | carolShare |
| space | Personal |
| sharee | Brian |
| shareType | user |
| permissionsRole | Editor |
And user "Brian" has a share "carolShare" synced
When user "Brian" moves file "aliceFile.txt" from share "aliceShare" to "carolFile.txt" in share "carolShare" using the WebDAV API
Then the HTTP status code should be "502"
And for user "Carol" the content of the file "carolShare/carolFile.txt" of the space "Personal" should be "from Carol"
And for user "Alice" the content of the file "aliceShare/aliceFile.txt" of the space "Personal" should be "from Alice"
@issue-8124
Scenario Outline: move a file from share to personal space
Given user "Brian" has been created with default attributes
@@ -0,0 +1,49 @@
Feature: access the space of the share owner using the drive id
As a user
I want the sharee to only access the shared resource
So that the rest of my space stays private
Background:
Given using spaces DAV path
And these users have been created with default attributes:
| username |
| Alice |
| Brian |
And user "Alice" has created folder "folderToShare"
And user "Alice" has uploaded file with content "inside" to "folderToShare/inside.txt"
And user "Alice" has uploaded file with content "private" to "private.txt"
And user "Alice" has sent the following resource share invitation:
| resource | folderToShare |
| space | Personal |
| sharee | Brian |
| shareType | user |
| permissionsRole | Editor |
And user "Brian" has a share "folderToShare" synced
Scenario: sharee cannot access the space of the owner using its drive id
When user "Brian" lists the content of the space of the owner of share "folderToShare" using the WebDAV API
Then the HTTP status code should be "404"
When user "Brian" downloads file "private.txt" from the space of the owner of share "folderToShare" using the WebDAV API
Then the HTTP status code should be "404"
When user "Brian" uploads content "uploaded by Brian" to file "brian.txt" in the space of the owner of share "folderToShare" using the WebDAV API
Then the HTTP status code should be "404"
When user "Brian" creates folder "brianFolder" in the space of the owner of share "folderToShare" using the WebDAV API
Then the HTTP status code should be "404"
When user "Brian" deletes file "private.txt" from the space of the owner of share "folderToShare" using the WebDAV API
Then the HTTP status code should be "404"
And for user "Alice" the content of the file "private.txt" of the space "Personal" should be "private"
And for user "Alice" folder "/" of the space "Personal" should not contain these files:
| brian.txt |
| brianFolder |
Scenario: sharee cannot copy or move a file out of the shared folder into the space of the owner
When user "Brian" tries to copy file "inside.txt" from share "folderToShare" to "copied.txt" in the space of the owner using the WebDAV API
Then the HTTP status code should be "409"
When user "Brian" tries to move file "inside.txt" from share "folderToShare" to "moved.txt" in the space of the owner using the WebDAV API
Then the HTTP status code should be "409"
And for user "Alice" the content of the file "folderToShare/inside.txt" of the space "Personal" should be "inside"
And for user "Alice" folder "/" of the space "Personal" should not contain these files:
| copied.txt |
| moved.txt |