Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
@@ -0,0 +1,318 @@
Feature: download file
As a user
I want to be able to download files
So that I can work wih local copies of files on my client system
Background:
Given user "Alice" has been created with default attributes
@smokeTest
Scenario Outline: download a file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "КуСфера test text file 0" to "/textfile0.txt"
When user "Alice" downloads file "/textfile0.txt" using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "КуСфера test text file 0"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@issue-1346
Scenario Outline: download a file with range
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "Welcome this is just an example file for developers." to "/welcome.txt"
When user "Alice" downloads file "/welcome.txt" with range "bytes=24-50" using the WebDAV API
Then the HTTP status code should be "206"
And the downloaded content should be "example file for developers"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a file larger than 4MB (ref: https://github.com/sabre-io/http/pull/119 )
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file "/file9000000.txt" ending with "text at end of file" of size 9000000 bytes
When user "Alice" downloads file "/file9000000.txt" using the WebDAV API
Then the HTTP status code should be "200"
And the size of the downloaded file should be 9000000 bytes
And the downloaded content should end with "text at end of file"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: get the size of a file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "This is a test file" to "test-file.txt"
When user "Alice" gets the size of file "test-file.txt" using the WebDAV API
Then the HTTP status code should be "207"
And the size of the file should be "19"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@issue-1316
Scenario Outline: get the content-length response header of a pdf file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file "filesForUpload/simple.pdf" to "/simple.pdf"
When user "Alice" downloads file "/simple.pdf" using the WebDAV API
Then the HTTP status code should be "200"
And the following headers should be set
| header | value |
| Content-Length | 17684 |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@issue-1316
Scenario Outline: get the content-length response header of an image file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file "filesForUpload/testavatar.png" to "/testavatar.png"
When user "Alice" downloads file "/testavatar.png" using the WebDAV API
Then the HTTP status code should be "200"
And the following headers should be set
| header | value |
| Content-Length | 47488 |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a file with comma in the filename
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "file with comma in filename" to <file-name>
When user "Alice" downloads file <file-name> using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "file with comma in filename"
Examples:
| dav-path-version | file-name |
| old | "sample,1.txt" |
| old | ",,,.txt" |
| old | ",,,.," |
| new | "sample,1.txt" |
| new | ",,,.txt" |
| new | ",,,.," |
| spaces | "sample,1.txt" |
| spaces | ",,,.txt" |
| spaces | ",,,.," |
Scenario Outline: download a file with single part ranges
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "Welcome this is just an example file for developers." to "/welcome.txt"
When user "Alice" downloads file "/welcome.txt" with range "bytes=0-51" using the WebDAV API
Then the HTTP status code should be "206"
And the following headers should be set
| header | value |
| Content-Length | 52 |
| Content-Range | bytes 0-51/52 |
And the downloaded content should be "Welcome this is just an example file for developers."
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a file with multipart ranges
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "Welcome this is just an example file for developers." to "/welcome.txt"
When user "Alice" downloads file "/welcome.txt" with range "bytes=0-6, 40-51" using the WebDAV API
Then the HTTP status code should be "206" or "200"
And if the HTTP status code was "206" then the following headers should match these regular expressions
| Content-Length | /\d+/ |
| Content-Type | /^multipart\/byteranges; boundary=[a-zA-Z0-9_.-]*$/ |
And if the HTTP status code was "206" then the downloaded content for multipart byterange should be:
"""
Content-Range: bytes 0-6/52
Content-Type: text/plain;charset=UTF-8
Welcome
Content-Range: bytes 40-51/52
Content-Type: text/plain;charset=UTF-8
developers.
"""
But if the HTTP status code was "200" then the downloaded content should be "Welcome this is just an example file for developers."
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a file with last byte range out of bounds
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "Welcome this is just an example file for developers." to "/welcome.txt"
When user "Alice" downloads file "/welcome.txt" with range "bytes=0-55" using the WebDAV API
Then the HTTP status code should be "206"
And the downloaded content should be "Welcome this is just an example file for developers."
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a range at the end of a file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "Welcome this is just an example file for developers." to "/welcome.txt"
When user "Alice" downloads file "/welcome.txt" with range "bytes=-11" using the WebDAV API
Then the HTTP status code should be "206"
And the downloaded content should be "developers."
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a file with range out of bounds
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "Welcome this is just an example file for developers." to "/welcome.txt"
When user "Alice" downloads file "/welcome.txt" with range "bytes=55-60" using the WebDAV API
Then the HTTP status code should be "416"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download hidden files
Given using <dav-path-version> DAV path
And user "Alice" has created folder "/FOLDER"
And user "Alice" has uploaded the following files with content "hidden file"
| path |
| .hidden_file |
| /FOLDER/.hidden_file |
When user "Alice" downloads the following files using the WebDAV API
| path |
| .hidden_file |
| /FOLDER/.hidden_file |
Then the HTTP status code of responses on all endpoints should be "200"
And the content of the following files for user "Alice" should be "hidden file"
| path |
| .hidden_file |
| /FOLDER/.hidden_file |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@smokeTest @issue-8361 @skipOnReva
Scenario Outline: downloading a file should serve security headers
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "test file" to "/<file-name>"
When user "Alice" downloads file "/<file-name>" using the WebDAV API
Then the HTTP status code should be "200"
And the following headers should be set
| header | value |
| Content-Disposition | attachment; filename*=UTF-8''<encoded-file-name>; filename="<file-name>" |
| Content-Security-Policy | child-src 'self'; connect-src 'self' blob: https://raw.githubusercontent.com/qsfera-eu/awesome-apps/ https://update.qsfera.eu/; default-src 'none'; font-src 'self'; frame-ancestors 'self'; frame-src 'self' blob: https://embed.diagrams.net/; img-src 'self' data: blob: https://raw.githubusercontent.com/qsfera-eu/awesome-apps/; manifest-src 'self'; media-src 'self'; object-src 'self' blob:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' |
| X-Content-Type-Options | nosniff |
| X-Frame-Options | SAMEORIGIN |
| X-Permitted-Cross-Domain-Policies | none |
| X-Robots-Tag | none |
| X-XSS-Protection | 1; mode=block |
And the downloaded content should be "test file"
Examples:
| dav-path-version | file-name | encoded-file-name |
| old | textfile.txt | textfile.txt |
| old | comma,.txt | comma%2C.txt |
| old | 'quote'single'.txt | %27quote%27single%27.txt |
| new | textfile.txt | textfile.txt |
| new | comma,.txt | comma%2C.txt |
| new | 'quote'single'.txt | %27quote%27single%27.txt |
| spaces | textfile.txt | textfile.txt |
| spaces | comma,.txt | comma%2C.txt |
| spaces | 'quote'single'.txt | %27quote%27single%27.txt |
@smokeTest @issue-8361 @skipOnReva
Scenario Outline: downloading a file should serve security headers (file with double quotes)
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "test file" to '/"quote"double".txt'
When user "Alice" downloads file '/"quote"double".txt' using the WebDAV API
Then the HTTP status code should be "200"
And the following headers should be set
| header | value |
| Content-Disposition | attachment; filename*=UTF-8''%22quote%22double%22.txt; filename=""quote"double".txt" |
| Content-Security-Policy | child-src 'self'; connect-src 'self' blob: https://raw.githubusercontent.com/qsfera-eu/awesome-apps/ https://update.qsfera.eu/; default-src 'none'; font-src 'self'; frame-ancestors 'self'; frame-src 'self' blob: https://embed.diagrams.net/; img-src 'self' data: blob: https://raw.githubusercontent.com/qsfera-eu/awesome-apps/; manifest-src 'self'; media-src 'self'; object-src 'self' blob:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' |
| X-Content-Type-Options | nosniff |
| X-Frame-Options | SAMEORIGIN |
| X-Permitted-Cross-Domain-Policies | none |
| X-Robots-Tag | none |
| X-XSS-Protection | 1; mode=block |
And the downloaded content should be "test file"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: download a zero byte size file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file "filesForUpload/zerobyte.txt" to "/zerobyte.txt"
When user "Alice" downloads file "/zerobyte.txt" using the WebDAV API
Then the HTTP status code should be "200"
And the size of the downloaded file should be 0 bytes
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: try to download recently deleted file
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "КуСфера test text file 0" to "/textfile0.txt"
When user "Alice" deletes file "textfile0.txt" using the WebDAV API
Then the HTTP status code should be "204"
When user "Alice" tries to download file "textfile0.txt" using the WebDAV API
Then the HTTP status code should be "404"
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@web-issue-1893
Scenario Outline: download a file with special characters in the filename
Given using <dav-path-version> DAV path
And user "Alice" has uploaded file with content "test file" to <file-name>
When user "Alice" downloads file <file-name> using the WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "test file"
Examples:
| dav-path-version | file-name |
| old | "😀 🤖.txt" |
| old | "" |
| old | "C++ file.cpp" |
| old | "file #2.txt" |
| old | "file ?2.pdf" |
| new | "😀 🤖.txt" |
| new | "" |
| new | "C++ file.cpp" |
| new | "file #2.txt" |
| new | "file ?2.pdf" |
| spaces | "😀 🤖.txt" |
| spaces | "" |
| spaces | "C++ file.cpp" |
| spaces | "file #2.txt" |
| spaces | "file ?2.pdf" |
@@ -0,0 +1,223 @@
Feature: list files
As a user
I want to be able to list my files and folders (resources)
So that I can understand my file structure in КуСфера
Background:
Given user "Alice" has been created with default attributes
And user "Alice" has created the following folders
| path |
| simple-folder |
| simple-folder/simple-folder1 |
| simple-folder/simple-empty-folder |
| simple-folder/simple-folder1/simple-folder2 |
And user "Alice" has uploaded the following files with content "simple-test-content"
| path |
| textfile0.txt |
| welcome.txt |
| simple-folder/textfile0.txt |
| simple-folder/welcome.txt |
| simple-folder/simple-folder1/textfile0.txt |
| simple-folder/simple-folder1/welcome.txt |
| simple-folder/simple-folder1/simple-folder2/textfile0.txt |
| simple-folder/simple-folder1/simple-folder2/welcome.txt |
Scenario Outline: get the list of resources in the root folder with depth 0
Given using <dav-path-version> DAV path
When user "Alice" lists the resources in "/" with depth "0" using the WebDAV API
Then the HTTP status code should be "207"
And the last DAV response for user "Alice" should not contain these nodes
| name |
| textfile0.txt |
| welcome.txt |
| simple-folder/ |
| simple-folder/welcome.txt |
| simple-folder/textfile0.txt |
| simple-folder/simple-empty-folder |
| simple-folder/simple-folder1 |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: get the list of resources in the root folder with depth 1
Given using <dav-path-version> DAV path
When user "Alice" lists the resources in "/" with depth "1" using the WebDAV API
Then the HTTP status code should be "207"
And the last DAV response for user "Alice" should contain these nodes
| name |
| textfile0.txt |
| welcome.txt |
| simple-folder/ |
And the last DAV response for user "Alice" should not contain these nodes
| name |
| simple-folder/welcome.txt |
| simple-folder/textfile0.txt |
| simple-folder/simple-empty-folder |
| simple-folder/simple-folder1 |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: get the list of resources in a folder with depth 0
Given using <dav-path-version> DAV path
When user "Alice" lists the resources in "/simple-folder" with depth "0" using the WebDAV API
Then the HTTP status code should be "207"
And the last DAV response for user "Alice" should contain these nodes
| name |
| simple-folder/ |
And the last DAV response for user "Alice" should not contain these nodes
| name |
| simple-folder/welcome.txt |
| simple-folder/textfile0.txt |
| simple-folder/simple-empty-folder |
| simple-folder/simple-folder1 |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: get the list of resources in a folder with depth 1
Given using <dav-path-version> DAV path
When user "Alice" lists the resources in "/simple-folder" with depth "1" using the WebDAV API
Then the HTTP status code should be "207"
And the last DAV response for user "Alice" should contain these nodes
| name |
| simple-folder/welcome.txt |
| simple-folder/textfile0.txt |
| simple-folder/simple-empty-folder |
| simple-folder/simple-folder1 |
And the last DAV response for user "Alice" should not contain these nodes
| name |
| simple-folder/simple-folder1/simple-folder2 |
| simple-folder/simple-folder1/textfile0.txt |
| simple-folder/simple-folder1/welcome.txt |
| simple-folder/simple-folder1/simple-folder2/textfile0.txt |
| simple-folder/simple-folder1/simple-folder2/welcome.txt |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@env-config @issue-10071 @issue-10331
Scenario: get the list of resources in a folder shared through public link with depth 0
Given using new DAV path
And the config "OC_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD" has been set to "false"
And user "Alice" has created the following folders
| path |
| /simple-folder/simple-folder1/simple-folder2/simple-folder3 |
| /simple-folder/simple-folder1/simple-folder2/simple-folder3/simple-folder4 |
And using SharingNG
And user "Alice" has created the following resource link share:
| resource | simple-folder |
| space | Personal |
| permissionsRole | view |
When the public lists the resources in the last created public link with depth "0" using the WebDAV API
Then the HTTP status code should be "207"
And the last public link DAV response should not contain these nodes
| name |
| /textfile0.txt |
| /welcome.txt |
| /simple-folder1/ |
| /simple-folder1/welcome.txt |
| /simple-folder1/simple-folder2 |
| /simple-folder1/textfile0.txt |
| /simple-folder1/simple-folder2/textfile0.txt |
| /simple-folder1/simple-folder2/welcome.txt |
| /simple-folder1/simple-folder2/simple-folder3 |
| /simple-folder1/simple-folder2/simple-folder3/simple-folder4 |
@env-config @issue-10071 @issue-10331
Scenario: get the list of resources in a folder shared through public link with depth 1
Given using new DAV path
And the config "OC_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD" has been set to "false"
And user "Alice" has created the following folders
| path |
| /simple-folder/simple-folder1/simple-folder2/simple-folder3 |
| /simple-folder/simple-folder1/simple-folder2/simple-folder3/simple-folder4 |
And using SharingNG
And user "Alice" has created the following resource link share:
| resource | simple-folder |
| space | Personal |
| permissionsRole | view |
When the public lists the resources in the last created public link with depth "1" using the WebDAV API
Then the HTTP status code should be "207"
And the last public link DAV response should contain these nodes
| name |
| /textfile0.txt |
| /welcome.txt |
| /simple-folder1/ |
And the last public link DAV response should not contain these nodes
| name |
| /simple-folder1/simple-folder2/textfile0.txt |
| /simple-folder1/simple-folder2/welcome.txt |
| /simple-folder1/simple-folder2/simple-folder3 |
| /simple-folder1/welcome.txt |
| /simple-folder1/simple-folder2 |
| /simple-folder1/textfile0.txt |
| /simple-folder1/simple-folder2/simple-folder3/simple-folder4 |
Scenario Outline: get the list of files in the trashbin with depth 0
Given using <dav-path-version> DAV path
And user "Alice" has deleted the following resources
| path |
| textfile0.txt |
| welcome.txt |
| simple-folder/ |
When user "Alice" lists the resources in the trashbin with depth "0" using the WebDAV API
Then the HTTP status code should be "207"
And the trashbin DAV response should not contain these nodes
| name |
| textfile0.txt |
| welcome.txt |
| simple-folder/ |
| simple-folder/textfile0.txt |
| simple-folder/welcome.txt |
| simple-folder/simple-folder1/textfile0.txt |
| simple-folder/simple-folder1/welcome.txt |
| simple-folder/simple-folder1/simple-folder2/textfile0.txt |
| simple-folder/simple-folder1/simple-folder2/welcome.txt |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
Scenario Outline: get the list of files in the trashbin with depth 1
Given using <dav-path-version> DAV path
And user "Alice" has deleted the following resources
| path |
| textfile0.txt |
| welcome.txt |
| simple-folder/ |
When user "Alice" lists the resources in the trashbin with depth "1" using the WebDAV API
Then the HTTP status code should be "207"
And the trashbin DAV response should contain these nodes
| name |
| textfile0.txt |
| welcome.txt |
| simple-folder/ |
And the trashbin DAV response should not contain these nodes
| name |
| simple-folder/textfile0.txt |
| simple-folder/welcome.txt |
| simple-folder/simple-folder1/textfile0.txt |
| simple-folder/simple-folder1/welcome.txt |
| simple-folder/simple-folder1/simple-folder2/textfile0.txt |
| simple-folder/simple-folder1/simple-folder2/welcome.txt |
Examples:
| dav-path-version |
| old |
| new |
| spaces |
@@ -0,0 +1,80 @@
Feature: PROPFIND
As a user
I want to retrieve all properties of a resource
So that I can get the information about a resource
@issue-751
Scenario Outline: send PROPFIND request to "/dav/(files|spaces)"
Given user "Alice" has been created with default attributes
When user "Alice" requests "<dav-path>" with "PROPFIND" using basic auth
Then the HTTP status code should be "405"
Examples:
| dav-path |
| /dav/files |
| /dav/spaces |
@issue-10334
Scenario Outline: send PROPFIND request to "/dav/(files|spaces)" with depth header
Given user "Alice" has been created with default attributes
When user "Alice" requests "<dav-path>" with "PROPFIND" using basic auth and with headers
| header | value |
| depth | <depth> |
Then the HTTP status code should be "<http-status-code>"
Examples:
| dav-path | depth | http-status-code |
| /webdav | 0 | 207 |
| /webdav | 1 | 207 |
| /dav/files/alice | 0 | 207 |
| /dav/files/alice | 1 | 207 |
| /dav/spaces/%spaceid% | 0 | 207 |
| /dav/spaces/%spaceid% | 1 | 207 |
| /dav/spaces/%spaceid% | infinity | 400 |
@skipOnReva
Examples:
| dav-path | depth | http-status-code |
| /webdav | infinity | 400 |
| /dav/files/alice | infinity | 400 |
@skipOnReva @issue-10071 @issue-10331
Scenario: send PROPFIND request to a public link shared with password
Given user "Alice" has been created with default attributes
And user "Alice" has created folder "/PARENT"
And using SharingNG
And user "Alice" has created the following resource link share:
| resource | PARENT |
| space | Personal |
| permissionsRole | view |
| password | %public% |
When the public sends "PROPFIND" request to the last public link share using the public WebDAV API with password "%public%"
Then the HTTP status code should be "207"
And the value of the item "//d:href" in the response should match "/\/dav\/public-files\/%public_token%\/$/"
And the value of the item "//oc:public-link-share-owner" in the response should be "Alice"
@skipOnReva @issue-10071 @issue-10331
Scenario: send PROPFIND request to a public link shared with password (request without password)
Given user "Alice" has been created with default attributes
And user "Alice" has created folder "/PARENT"
And using SharingNG
And user "Alice" has created the following resource link share:
| resource | PARENT |
| space | Personal |
| permissionsRole | view |
| password | %public% |
When the public sends "PROPFIND" request to the last public link share using the public WebDAV API
Then the HTTP status code should be "401"
And the value of the item "/d:error/s:exception" in the response should be "Sabre\DAV\Exception\NotAuthenticated"
@skipOnReva @issue-10071 @issue-10331
Scenario: send PROPFIND request to a public link shared with password (request with incorrect password)
Given user "Alice" has been created with default attributes
And user "Alice" has created folder "/PARENT"
And using SharingNG
And user "Alice" has created the following resource link share:
| resource | PARENT |
| space | Personal |
| permissionsRole | view |
| password | %public% |
When the public sends "PROPFIND" request to the last public link share using the public WebDAV API with password "1234"
Then the HTTP status code should be "401"
And the value of the item "/d:error/s:exception" in the response should be "Sabre\DAV\Exception\NotAuthenticated"
@@ -0,0 +1,36 @@
Feature: refuse access
As an administrator
I want to refuse access to unauthenticated and disabled users
So that I can secure the system
Background:
Given using OCS API version "1"
@smokeTest @issue-2285
Scenario Outline: unauthenticated call
# cannot perform with spaces WebDAV due to the absence of user
Given using <dav-path-version> DAV path
When an unauthenticated client connects to the DAV endpoint using the WebDAV API
Then the HTTP status code should be "401"
And there should be no duplicate headers
And the following headers should be set
| header | value |
| WWW-Authenticate | Basic realm="%productname%", charset="UTF-8" |
Examples:
| dav-path-version |
| old |
| new |
@issue-2285
Scenario Outline: disabled user cannot use webdav
Given using <dav-path-version> DAV path
And user "Alice" has been created with default attributes
And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "textfile0.txt"
And user "Alice" has been disabled
When user "Alice" downloads file "/textfile0.txt" using the WebDAV API
Then the HTTP status code should be "401"
Examples:
| dav-path-version |
| old |
| new |
| spaces |