diff --git a/.drone.env b/.drone.env index 9ef0abd9c..2dce41d86 100644 --- a/.drone.env +++ b/.drone.env @@ -1,5 +1,5 @@ # The test runner source for API tests -CORE_COMMITID=0214d4bca2d0bb39ea6b2ad67c2df463b2647b76 +CORE_COMMITID=f0a417390cf43d9e91e440dc631a7d3cc2b673b8 CORE_BRANCH=master # The test runner source for UI tests diff --git a/tests/acceptance/features/apiSpaces/shareSpacesViaLink.feature b/tests/acceptance/features/apiSpaces/shareSpacesViaLink.feature new file mode 100644 index 000000000..f6178aa79 --- /dev/null +++ b/tests/acceptance/features/apiSpaces/shareSpacesViaLink.feature @@ -0,0 +1,85 @@ +@api @skipOnOcV10 +Feature: Share spaces via link + As the manager of a space + I want to be able to share a space via public link + + Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production + See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839 + + Background: + Given these users have been created with default attributes and without skeleton files: + | username | + | Alice | + | Brian | + And the administrator has given "Alice" the role "Space Admin" using the settings api + And user "Alice" has created a space "share space" with the default quota using the GraphApi + And user "Alice" has uploaded a file inside space "share space" with content "some content" to "test.txt" + + + Scenario Outline: A manager can share a space to public via link with different permissions + When user "Alice" creates a public link share of the space "share space" with settings: + | permissions | | + | password | | + | name | | + | expireDate | | + Then the HTTP status code should be "200" + And the OCS status code should be "200" + And the OCS status message should be "OK" + And the fields of the last response to user "Alice" should include + | item_type | folder | + | mimetype | httpd/unix-directory | + | file_target | / | + | path | / | + | permissions | | + | share_type | public_link | + | displayname_file_owner | %displayname% | + | displayname_owner | %displayname% | + | uid_file_owner | %username% | + | uid_owner | %username% | + | name | | + And the public should be able to download file "/test.txt" from inside the last public link shared folder using the new public WebDAV API with password "123" + And the downloaded content should be "some content" + Examples: + | permissions | expectedPermissions | password | linkName | expireDate | + | 1 | read | 123 | link | 2042-03-25T23:59:59+0100 | + | 5 | read,create | 123 | | 2042-03-25T23:59:59+0100 | + | 15 | read,update,create,delete | | link | | + + + Scenario: An uploader should be able to upload a file + When user "Alice" creates a public link share of the space "share space" with settings: + | permissions | 4 | + | password | 123 | + | name | forUpload | + | expireDate | 2042-03-25T23:59:59+0100 | + Then the HTTP status code should be "200" + And the OCS status code should be "200" + And the OCS status message should be "OK" + And the fields of the last response to user "Alice" should include + | item_type | folder | + | mimetype | httpd/unix-directory | + | file_target | / | + | path | / | + | permissions | create | + | share_type | public_link | + | displayname_file_owner | %displayname% | + | displayname_owner | %displayname% | + | uid_file_owner | %username% | + | uid_owner | %username% | + | name | forUpload | + And the public should be able to upload file "lorem.txt" into the last public link shared folder using the new public WebDAV API with password "123" + And for user "Alice" the space "share space" should contain these entries: + | lorem.txt | + + + Scenario Outline: An user without manager role cannot share a space to public via link + Given user "Alice" has shared a space "share space" to user "Brian" with role "" + When user "Brian" creates a public link share of the space "share space" with settings: + | permissions | 1 | + Then the HTTP status code should be "404" + And the OCS status code should be "404" + And the OCS status message should be "No share permission" + Examples: + | role | + | viewer | + | editor | diff --git a/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature b/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature index b38d3399f..017ef55b9 100644 --- a/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature +++ b/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature @@ -111,9 +111,9 @@ Feature: Share a file or folder that is inside a space via public link | displayname_owner | %displayname% | | uid_file_owner | %username% | | uid_owner | %username% | - And the public should be able to download the last publicly shared file using the public WebDAV API without a password and the content should be "Random data" - And the public upload to the last publicly shared file using the public WebDAV API should pass with HTTP status code "204" + And the public should be able to download the last publicly shared file using the new public WebDAV API without a password and the content should be "Random data" + And the public upload to the last publicly shared file using the new public WebDAV API should pass with HTTP status code "204" Examples: - | ocs_api_version | ocs_status_code | webdav_api_version | - | 1 | 100 | new | - | 2 | 200 | new | + | ocs_api_version | ocs_status_code | + | 1 | 100 | + | 2 | 200 | diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 31eaa26d8..4e1a1be02 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -125,6 +125,11 @@ class SpacesContext implements Context { */ private array $availableSpaces; + /** + * @var array + */ + private array $lastPublicLinkData = []; + /** * @return array */ @@ -502,6 +507,7 @@ class SpacesContext implements Context { * @param string $password * @param string $xRequestId * @param array $headers + * @param mixed $body * * @return ResponseInterface * @@ -512,9 +518,10 @@ class SpacesContext implements Context { string $user, string $password, string $xRequestId = '', - array $headers = [] + array $headers = [], + $body = null ): ResponseInterface { - return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PROPFIND', $user, $password, $headers); + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PROPFIND', $user, $password, $headers, $body); } /** @@ -542,6 +549,57 @@ class SpacesContext implements Context { return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PUT', $user, $password, $headers, $content); } + /** + * Send POST Request to url + * + * @param string $fullUrl + * @param string $user + * @param string $password + * @param mixed $body + * @param string $xRequestId + * @param array $headers + * + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function sendPostRequestToUrl( + string $fullUrl, + string $user, + string $password, + $body, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface { + return HttpRequestHelper::post($fullUrl, $xRequestId, $user, $password, $headers, $body); + } + + /** + * Send Graph Create Folder Request + * + * @param string $fullUrl + * @param string $method + * @param string $user + * @param string $password + * @param string $xRequestId + * @param array $headers + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function sendCreateFolderRequest( + string $fullUrl, + string $method, + string $user, + string $password, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface { + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, $method, $user, $password, $headers); + } + /** * @When /^user "([^"]*)" lists all available spaces via the GraphApi$/ * @When /^user "([^"]*)" lists all available spaces via the GraphApi with query "([^"]*)"$/ @@ -683,13 +741,13 @@ class SpacesContext implements Context { public function theAdministratorGivesUserTheRole(string $user, string $role): void { $admin = $this->featureContext->getAdminUsername(); $password = $this->featureContext->getAdminPassword(); - $headers = []; $bundles = []; $assignment = []; // get the roles list first $fullUrl = $this->baseUrl . "/api/v0/settings/roles-list"; - $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, "{}")); + $this->featureContext->setResponse($this->sendPostRequestToUrl($fullUrl, $admin, $password, "{}")); + if ($this->featureContext->getResponse()) { $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"])) { @@ -727,7 +785,7 @@ class SpacesContext implements Context { $fullUrl = $this->baseUrl . "/api/v0/settings/assignments-add"; $body = json_encode(["account_uuid" => $accountToChange["id"], "role_id" => $roleToAssign["id"]], JSON_THROW_ON_ERROR); - $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, $body)); + $this->featureContext->setResponse($this->sendPostRequestToUrl($fullUrl, $admin, $password, $body)); if ($this->featureContext->getResponse()) { $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"])) { @@ -787,8 +845,8 @@ class SpacesContext implements Context { $spaceWebDavUrl . '/' . $foldersPath, $user, $this->featureContext->getPasswordForUser($user), - "", - $headers, + '', + $headers ) ); $this->setResponseSpaceId($spaceId); @@ -1410,31 +1468,6 @@ class SpacesContext implements Context { ); } - /** - * Send Graph Create Folder Request - * - * @param string $fullUrl - * @param string $method - * @param string $user - * @param string $password - * @param string $xRequestId - * @param array $headers - * - * @return ResponseInterface - * - * @throws GuzzleException - */ - public function sendCreateFolderRequest( - string $fullUrl, - string $method, - string $user, - string $password, - string $xRequestId = '', - array $headers = [] - ): ResponseInterface { - return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, $method, $user, $password, $headers); - } - /** * @When /^user "([^"]*)" changes the name of the "([^"]*)" space to "([^"]*)"$/ * @@ -1842,12 +1875,10 @@ class SpacesContext implements Context { $fullUrl = $this->baseUrl . $this->ocsApiUrl; $this->featureContext->setResponse( - HttpRequestHelper::post( + $this->sendPostRequestToUrl( $fullUrl, - "", $user, $this->featureContext->getPasswordForUser($user), - [], $body ) ); @@ -1883,12 +1914,10 @@ class SpacesContext implements Context { $fullUrl = $this->baseUrl . $this->ocsApiUrl; $this->featureContext->setResponse( - HttpRequestHelper::post( + $this->sendPostRequestToUrl( $fullUrl, - "", $user, $this->featureContext->getPasswordForUser($user), - [], $body ) ); @@ -1931,12 +1960,10 @@ class SpacesContext implements Context { $fullUrl = $this->baseUrl . $this->ocsApiUrl; $this->featureContext->setResponse( - HttpRequestHelper::post( + $this->sendPostRequestToUrl( $fullUrl, - "", $user, $this->featureContext->getPasswordForUser($user), - [], $body ) ); @@ -2211,14 +2238,10 @@ class SpacesContext implements Context { $space = $this->getSpaceByName($user, $spaceName); $fullUrl = $this->baseUrl . $this->davSpacesUrl . "trash-bin/" . $space["id"]; $this->featureContext->setResponse( - HttpRequestHelper::sendRequest( + $this->sendPropfindRequestToUrl( $fullUrl, - "", - 'PROPFIND', $user, - $this->featureContext->getPasswordForUser($user), - [], - "" + $this->featureContext->getPasswordForUser($user) ) ); } @@ -2469,14 +2492,10 @@ class SpacesContext implements Context { $fullUrl = $this->baseUrl . '/remote.php/dav/meta/' . $fileId . '/v'; $this->featureContext->setResponse( - HttpRequestHelper::sendRequest( + $this->sendPropfindRequestToUrl( $fullUrl, - "", - 'PROPFIND', $user, - $this->featureContext->getPasswordForUser($user), - [], - "" + $this->featureContext->getPasswordForUser($user) ) ); @@ -2499,12 +2518,11 @@ class SpacesContext implements Context { $space = $this->getSpaceByName($user, $space); $fullUrl = $space['root']['webDavUrl'] . '/' . ltrim($path, '/'); - $response = HttpRequestHelper::sendRequest( + $response = $this->sendPropfindRequestToUrl( $fullUrl, - $this->featureContext->getStepLineRef(), - 'PROPFIND', $user, $this->featureContext->getPasswordForUser($user), + $this->featureContext->getStepLineRef(), [], $this->etagPropfindBody ); @@ -2653,4 +2671,52 @@ class SpacesContext implements Context { throw new Exception("Expected stored etag to be some string but found null!"); } } + + /** + * @When /^user "([^"]*)" creates a public link share of the space "([^"]*)" with settings:$/ + * + * @param string $user + * @param string $spaceName + * @param TableNode|null $table + * + * @return void + * @throws GuzzleException + */ + public function sendShareSpaceViaLinkRequest( + string $user, + string $spaceName, + ?TableNode $table + ): void { + $space = $this->getSpaceByName($user, $spaceName); + $rows = $table->getRowsHash(); + + $rows["shareType"] = \array_key_exists("shareType", $rows) ? $rows["shareType"] : 3; + $rows["permissions"] = \array_key_exists("permissions", $rows) ? $rows["permissions"] : null; + $rows["password"] = \array_key_exists("password", $rows) ? $rows["password"] : null; + $rows["name"] = \array_key_exists("name", $rows) ? $rows["name"] : null; + $rows["expireDate"] = \array_key_exists("expireDate", $rows) ? $rows["expireDate"] : null; + + $body = [ + "space_ref" => $space['id'], + "shareType" => $rows["shareType"], + "permissions" => $rows["permissions"], + "password" => $rows["password"], + "name" => $rows["name"], + "expireDate" => $rows["expireDate"] + ]; + + $fullUrl = $this->baseUrl . $this->ocsApiUrl; + + $this->featureContext->setResponse( + $this->sendPostRequestToUrl( + $fullUrl, + $user, + $this->featureContext->getPasswordForUser($user), + $body + ) + ); + + // set last response as PublicShareData. using method from core + $this->featureContext->setLastPublicShareData($this->featureContext->getResponseXml(null, __METHOD__)); + } }