Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions tests/acceptance/bootstrap/GuestLinkContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,76 @@ public function guestListsTheSharesSharedWithThem(string $guest): void {
);
}

/**
* @param string $guest
* @param string $authorization
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest lists the shares shared with them with authorization header :authorization using the Graph API')]
public function guestListsTheSharesSharedWithThemWithAuthorizationHeader(
string $guest,
string $authorization
): void {
$this->featureContext->setResponse(
HttpRequestHelper::get(
$this->featureContext->getBaseUrl() . '/graph/v1beta1/me/drive/sharedWithMe',
$this->featureContext->getStepLineRef(),
null,
null,
\array_merge($this->getSessionHeaders($guest), ['Authorization' => $authorization]),
)
);
}

/**
* @param string $user
* @param string $guest
*
* @return void
* @throws GuzzleException
*/
#[When('user :user lists the shares shared with them with the guest session of guest :guest using the Graph API')]
public function userListsTheSharesSharedWithThemWithTheGuestSession(string $user, string $guest): void {
$this->featureContext->setResponse(
HttpRequestHelper::get(
$this->featureContext->getBaseUrl() . '/graph/v1beta1/me/drive/sharedWithMe',
$this->featureContext->getStepLineRef(),
$this->featureContext->getActualUsername($user),
$this->featureContext->getPasswordForUser($user),
$this->getSessionHeaders($guest),
)
);
}

/**
* @param string $guest
* @param string $resource
* @param string $password
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest downloads file :resource from the last public link share with password :password and the guest session using the public WebDAV API')]
public function guestDownloadsFileFromTheLastPublicLinkShareWithTheGuestSession(
string $guest,
string $resource,
string $password
): void {
$token = $this->featureContext->shareNgGetLastCreatedLinkShareToken();
$davPath = WebDavHelper::getDavPath(WebDavHelper::DAV_VERSION_NEW, $token, 'public-files');
$this->featureContext->setResponse(
HttpRequestHelper::get(
$this->featureContext->getBaseUrl() . "/$davPath/$resource",
$this->featureContext->getStepLineRef(),
'public',
$this->featureContext->getActualPassword($password),
\array_merge($this->getSessionHeaders($guest), ['public-token' => $token]),
)
);
}

/**
* @param string $guest
* @param string $resource
Expand Down Expand Up @@ -1014,6 +1084,144 @@ public function guestSendsHttpMethodToGraphEndpointOfResource(
);
}

/**
* @param string $fileId
* @param string|null $user
* @param array $headers
*
* @return string
* @throws GuzzleException
*/
private function getDownloadUrl(string $fileId, ?string $user, array $headers): string {
$response = WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
$user === null ? null : $this->featureContext->getActualUsername($user),
$user === null ? null : $this->featureContext->getPasswordForUser($user),
'PROPFIND',
'',
\array_merge($headers, ['Depth' => '0']),
$fileId,
$this->featureContext->getStepLineRef(),
WebDavHelper::getBodyForPropfind(['oc:downloadURL']),
WebDavHelper::DAV_VERSION_SPACES
);
$this->featureContext->theHTTPStatusCodeShouldBe(207, '', $response);
$match = HttpRequestHelper::getResponseXml($response, __METHOD__)->xpath('//d:prop/oc:downloadURL');
Assert::assertNotEmpty($match, 'The response does not contain an oc:downloadURL');
return (string)$match[0];
}

/**
* @param string $guest
* @param string $resource
* @param string $space
* @param string $owner
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest downloads file :resource shared from space :space of user :owner via its signed download URL')]
public function guestDownloadsSharedFileViaItsDownloadUrl(
string $guest,
string $resource,
string $space,
string $owner
): void {
$fileId = $this->spacesContext->getResourceId($owner, $space, $resource);
$headers = $this->getSessionHeaders($guest);
$this->featureContext->setResponse(
HttpRequestHelper::get(
$this->getDownloadUrl($fileId, null, $headers),
$this->featureContext->getStepLineRef(),
null,
null,
$headers,
)
);
}

/**
* @param string $user
* @param string $resource
* @param string $guest
*
* @return void
* @throws GuzzleException
*/
#[When('user :user downloads file :resource via its signed download URL with the guest session of guest :guest')]
public function userDownloadsFileViaItsDownloadUrlWithTheGuestSession(
string $user,
string $resource,
string $guest
): void {
$fileId = $this->spacesContext->getResourceId($user, 'Personal', $resource);
$this->featureContext->setResponse(
HttpRequestHelper::get(
$this->getDownloadUrl($fileId, $user, []),
$this->featureContext->getStepLineRef(),
null,
null,
$this->getSessionHeaders($guest),
)
);
}

/**
* @param string $guest
* @param string $content
* @param string $path
* @param string $folder
* @param string $space
* @param string $owner
* @param string $authorization
*
* @return void
* @throws GuzzleException
*/
#[When('guest :guest uploads content :content to :path inside folder :folder of space :space of user :owner using the TUS protocol with authorization header :authorization')]
public function guestUploadsContentInsideFolderUsingTusWithAuthorizationHeader(
string $guest,
string $content,
string $path,
string $folder,
string $space,
string $owner,
string $authorization
): void {
$folderId = $this->spacesContext->getResourceId($owner, $space, $folder);
$headers = \array_merge(
$this->getSessionHeaders($guest),
['Authorization' => $authorization, 'Tus-Resumable' => '1.0.0']
);
$response = WebDavHelper::makeDavRequest(
$this->featureContext->getBaseUrl(),
null,
null,
'POST',
'',
\array_merge(
$headers,
['Upload-Length' => (string)\strlen($content), 'Upload-Metadata' => 'filename ' . \base64_encode($path)]
),
$folderId,
$this->featureContext->getStepLineRef(),
null,
WebDavHelper::DAV_VERSION_SPACES
);
$this->featureContext->theHTTPStatusCodeShouldBe(201, '', $response);
$this->featureContext->setResponse(
HttpRequestHelper::sendRequest(
$response->getHeader('Location')[0],
$this->featureContext->getStepLineRef(),
'PATCH',
null,
null,
\array_merge($headers, ['Content-Type' => 'application/offset+octet-stream', 'Upload-Offset' => '0']),
$content,
)
);
}

/**
* @param string $guest
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
@email
Feature: guest session does not override other credentials
As a user who has opened a guest link in the same browser
I want requests with other credentials to never be authenticated as the guest
So that I get my own data, or a 401 to renew invalid credentials

Background:
Given user "Alice" has been created with default attributes
And user "Brian" has been created with default attributes
And user "Alice" has uploaded file with content "for guest" to "guestFile.txt"
And user "Alice" has sent the following resource share invitation:
| resource | guestFile.txt |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Viewer |
And guest "guest@example.org" has verified the guest link from the last email


Scenario Outline: request with invalid credentials and a guest session is rejected
When guest "guest@example.org" lists the shares shared with them with authorization header "<authorization>" using the Graph API
Then the HTTP status code should be "401"
Examples:
| authorization |
| Bearer invalid-token |
| Basic aW52YWxpZDppbnZhbGlk |


Scenario: request with valid user credentials and a guest session is authenticated as the user
When user "Brian" lists the shares shared with them with the guest session of guest "guest@example.org" 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": 0,
"maxItems": 0
}
}
}
"""


Scenario: public link request with a guest session is authenticated as the public link
Given user "Alice" has created folder "publicFolder"
And user "Alice" has uploaded file with content "public content" to "publicFolder/public.txt"
And user "Alice" has created the following resource link share:
| resource | publicFolder |
| space | Personal |
| permissionsRole | view |
| password | %public% |
When guest "guest@example.org" downloads file "public.txt" from the last public link share with password "%public%" and the guest session using the public WebDAV API
Then the HTTP status code should be "200"
And the downloaded content should be "public content"


Scenario: guest downloads a shared file via its signed download URL
When guest "guest@example.org" downloads file "guestFile.txt" shared from space "Personal" of user "Alice" via its signed download URL
Then the HTTP status code should be "200"
And the downloaded content should be "for guest"


Scenario: signed download URL of a user with a guest session is authenticated as the user
Given user "Brian" has uploaded file with content "from Brian" to "brianFile.txt"
When user "Brian" downloads file "brianFile.txt" via its signed download URL with the guest session of guest "guest@example.org"
Then the HTTP status code should be "200"
And the downloaded content should be "from Brian"


Scenario: guest uploads a file using TUS with an unusable authorization header
Given user "Alice" has created folder "uploadFolder"
And user "Alice" has sent the following resource share invitation:
| resource | uploadFolder |
| space | Personal |
| sharee | guest@example.org |
| shareType | guest |
| permissionsRole | Editor |
When guest "guest@example.org" uploads content "uploaded by guest" to "tus.txt" inside folder "uploadFolder" of space "Personal" of user "Alice" using the TUS protocol with authorization header "undefined"
Then the HTTP status code should be "204"
And the content of file "uploadFolder/tus.txt" for user "Alice" should be "uploaded by guest"
Loading