mirror of
https://github.com/nextcloud/richdocuments.git
synced 2025-12-17 21:12:14 +01:00
This is achieved by setting a specific DAV attribute. At the moment there is one handler in dav-apps FilesPlugin and it could overwrite the value with "false". We make sure not to downgrade here and prevent downgrade from dav (possible race condition). Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
315 lines
11 KiB
PHP
315 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
require __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use Behat\Behat\Context\Context;
|
|
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
|
|
use GuzzleHttp\Client;
|
|
use JuliusHaertl\NextcloudBehat\Context\FilesContext;
|
|
use JuliusHaertl\NextcloudBehat\Context\ServerContext;
|
|
use JuliusHaertl\NextcloudBehat\Context\SharingContext;
|
|
use PHPUnit\Framework\Assert;
|
|
|
|
class RichDocumentsContext implements Context {
|
|
/** @var ServerContext */
|
|
private $serverContext;
|
|
/** @var FilesContext */
|
|
private $filesContext;
|
|
/** @var SharingContext */
|
|
private $sharingContext;
|
|
/** @var WopiContext */
|
|
private $wopiContext;
|
|
|
|
public $currentServer;
|
|
public $fileId;
|
|
public $wopiToken;
|
|
/** @var array List of opened file ids in order to compare opening accross instances */
|
|
private $fileIds = [];
|
|
/** @var array List of templates fetched for a given file type */
|
|
private $templates = [];
|
|
private array $directoryListing = [];
|
|
|
|
/** @BeforeScenario */
|
|
public function gatherContexts(BeforeScenarioScope $scope) {
|
|
$environment = $scope->getEnvironment();
|
|
$this->serverContext = $environment->getContext(ServerContext::class);
|
|
$this->filesContext = $environment->getContext(FilesContext::class);
|
|
$this->sharingContext = $environment->getContext(SharingContext::class);
|
|
$this->wopiContext = $environment->getContext(WopiContext::class);
|
|
}
|
|
|
|
/**
|
|
* @When User :user opens :file
|
|
*/
|
|
public function userOpens($user, $file) {
|
|
$this->serverContext->usingWebAsUser($user);
|
|
$davClient = $this->filesContext->getSabreClient($user);
|
|
$path = $this->filesContext->makeSabrePath($user, $file);
|
|
$result = $davClient->propFind($path, ['{http://owncloud.org/ns}fileid']);
|
|
$fileId = $result['{http://owncloud.org/ns}fileid'];
|
|
|
|
$client = new Client();
|
|
$result = $client->get(
|
|
$this->serverContext->getBaseUrl() . 'index.php/apps/richdocuments/index?fileId=' . $fileId,
|
|
array_merge(
|
|
$this->serverContext->getWebOptions(),
|
|
[
|
|
'allow_redirects' => [
|
|
'track_redirects' => true
|
|
]
|
|
]
|
|
)
|
|
);
|
|
$redirects = $result->getHeader('X-Guzzle-Redirect-History');
|
|
$lastServer = array_pop($redirects);
|
|
if ($lastServer) {
|
|
$this->currentServer = parse_url($lastServer, PHP_URL_SCHEME) . '://' . parse_url($lastServer, PHP_URL_HOST) . (
|
|
parse_url($lastServer, PHP_URL_PORT) ? ':' . parse_url($lastServer, PHP_URL_PORT) : ''
|
|
) . '/';
|
|
}
|
|
$this->extractRichdocumentsFrontendContext($result);
|
|
|
|
Assert::assertNotEmpty($this->fileId);
|
|
Assert::assertNotEmpty($this->wopiToken);
|
|
}
|
|
|
|
/**
|
|
* @When the download button for :path will be visible to :user
|
|
*/
|
|
public function downloadButtonIsVisible(string $path, string $user): void {
|
|
$this->downloadButtonIsNotVisibleOrNot($path, $user, true);
|
|
}
|
|
|
|
/**
|
|
* @When the download button for :path will not be visible to :user
|
|
*/
|
|
public function downloadButtonIsNotVisible(string $path, string $user): void {
|
|
$this->downloadButtonIsNotVisibleOrNot($path, $user, false);
|
|
}
|
|
|
|
private function downloadButtonIsNotVisibleOrNot(string $path, string $user, bool $isVisible): void {
|
|
$hideDownloadProperty = '{http://nextcloud.org/ns}hide-download';
|
|
$this->serverContext->usingWebAsUser($user);
|
|
$fileInfo = $this->filesContext->listFolder($path, 0, [$hideDownloadProperty]);
|
|
|
|
if ($isVisible) {
|
|
Assert::assertTrue(!isset($fileInfo[$hideDownloadProperty]) || $fileInfo[$hideDownloadProperty] === 'false');
|
|
} else {
|
|
Assert::assertTrue(isset($fileInfo[$hideDownloadProperty]), 'property is not set');
|
|
Assert::assertTrue($fileInfo[$hideDownloadProperty] === 'true', 'property is not true');
|
|
Assert::assertTrue(isset($fileInfo[$hideDownloadProperty]) && $fileInfo[$hideDownloadProperty] === 'true');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @When the download button for :path will not be visible in the last link share
|
|
*/
|
|
public function theDownloadButtonWillNotBeVisibleInLastLinkShare(string $path): void {
|
|
$hideDownloadProperty = '{http://nextcloud.org/ns}hide-download';
|
|
$this->serverContext->usingWebAsUser();
|
|
$shareToken = $this->sharingContext->getLastShareData()['token'];
|
|
$davClient = $this->filesContext->getPublicSabreClient($shareToken);
|
|
$result = $davClient->propFind($path, ['{http://nextcloud.org/ns}hide-download'], 1);
|
|
$fileInfo = $result[array_key_first($result)];
|
|
Assert::assertTrue(!isset($fileInfo[$hideDownloadProperty]) || $fileInfo[$hideDownloadProperty] === 'true');
|
|
}
|
|
|
|
public function generateTokenWithApi($user, $fileId, ?string $shareToken = null, ?string $path = null, ?string $guestName = null) {
|
|
$this->serverContext->usingWebAsUser($user);
|
|
$this->serverContext->sendJSONRequest('POST', '/index.php/apps/richdocuments/token', [
|
|
'fileId' => $fileId,
|
|
'shareToken' => $shareToken,
|
|
'path' => $path,
|
|
'guestName' => $guestName,
|
|
]);
|
|
echo $this->serverContext->getResponse()->getStatusCode();
|
|
|
|
$response = $this->serverContext->getOCSResponse();
|
|
|
|
$this->fileId = $fileId . '_ocfake';
|
|
$this->fileIds[] = $this->fileId;
|
|
$this->wopiToken = $response['token'];
|
|
$this->wopiContext->setWopiParameters($this->currentServer, $this->fileId, $this->wopiToken);
|
|
|
|
Assert::assertNotEmpty($this->fileId);
|
|
Assert::assertNotEmpty($this->wopiToken);
|
|
}
|
|
|
|
|
|
/**
|
|
* @Then a guest opens the share link
|
|
*/
|
|
public function aGuestOpensTheShareLink() {
|
|
$this->aGuestOpensTheShareLinkAs();
|
|
}
|
|
|
|
/**
|
|
* @Then a guest opens the share link as :guestName
|
|
* @Then a guest opens the share link without guest name
|
|
*/
|
|
public function aGuestOpensTheShareLinkAs($guestName = null) {
|
|
$this->openTheShareLink(null, $guestName);
|
|
}
|
|
|
|
/**
|
|
* @Then the user opens the share link
|
|
*/
|
|
public function aUserOpensTheShareLink() {
|
|
$this->openTheShareLink($this->serverContext->getAuth()[0], null);
|
|
}
|
|
|
|
private function openTheShareLink($userId = null, $guestName = null, $fileId = null) {
|
|
if ($fileId === null) {
|
|
$fileId = $this->sharingContext->getLastShareData()['item_source'];
|
|
}
|
|
$shareToken = $this->sharingContext->getLastShareData()['token'];
|
|
$this->generateTokenWithApi($userId, $fileId, shareToken: $shareToken, guestName: $guestName);
|
|
}
|
|
|
|
/**
|
|
* @Given /^a guest opens the file "([^"]*)" of the shared link$/
|
|
*/
|
|
public function aGuestOpensTheFileOfTheSharedLink($file) {
|
|
$this->openTheShareLink(null, null, $this->getFileIdInLastShare($file));
|
|
}
|
|
|
|
/**
|
|
* @Given /^a guest opens the file "([^"]*)" of the shared link as "([^"]*)"$/
|
|
*/
|
|
public function aGuestOpensTheFileOfTheSharedLinkWithGuestName($file, $guestName) {
|
|
$this->openTheShareLink(null, $guestName, $this->getFileIdInLastShare($file));
|
|
}
|
|
|
|
/**
|
|
* @Given /^User "([^"]*)" opens the file "([^"]*)" of the shared link$/
|
|
*/
|
|
public function userOpensTheFileOfTheSharedLink($user, $file) {
|
|
$this->openTheShareLink($user, null, $this->getFileIdInLastShare($file));
|
|
}
|
|
|
|
private function getFileIdInLastShare($file) {
|
|
$shareToken = $this->sharingContext->getLastShareData()['token'];
|
|
$davClient = $this->filesContext->getPublicSabreClient($shareToken);
|
|
$path = $file;
|
|
$result = $davClient->propFind($path, ['{http://owncloud.org/ns}fileid']);
|
|
return $result['{http://owncloud.org/ns}fileid'];
|
|
}
|
|
|
|
/**
|
|
* @Given /^user "([^"]*)" fetches the (document|spreadsheet|presentation) template list$/
|
|
*/
|
|
public function userFetchesTheTemplateList($user, $type) {
|
|
$this->serverContext->sendOCSRequest('GET', '/apps/richdocuments/api/v1/templates/' . $type);
|
|
$this->templates = $this->serverContext->getOCSResponseData();
|
|
}
|
|
|
|
/**
|
|
* @Given /^user "([^"]*)" creates a new file "([^"]*)" from a template$/
|
|
*/
|
|
public function userCreatesANewFileFromATemplate($user, $file) {
|
|
$template = $this->templates[0];
|
|
$this->serverContext->usingWebAsUser($user);
|
|
|
|
$client = new Client();
|
|
$query = [
|
|
'templateId' => $template['id'],
|
|
'fileName' => basename($file),
|
|
'dir' => dirname($file),
|
|
];
|
|
$result = $client->get(
|
|
$this->serverContext->getBaseUrl() . 'index.php/apps/richdocuments/indexTemplate',
|
|
array_merge(
|
|
$this->serverContext->getWebOptions(),
|
|
[
|
|
'query' => $query,
|
|
'allow_redirects' => [
|
|
'track_redirects' => true
|
|
]
|
|
]
|
|
)
|
|
);
|
|
$redirects = $result->getHeader('X-Guzzle-Redirect-History');
|
|
$lastServer = array_pop($redirects);
|
|
if ($lastServer) {
|
|
$this->currentServer = parse_url($lastServer, PHP_URL_SCHEME) . '://' . parse_url($lastServer, PHP_URL_HOST) . (
|
|
parse_url($lastServer, PHP_URL_PORT) ? ':' . parse_url($lastServer, PHP_URL_PORT) : ''
|
|
) . '/';
|
|
}
|
|
$this->extractRichdocumentsFrontendContext($result);
|
|
|
|
Assert::assertNotEmpty($this->fileId);
|
|
Assert::assertNotEmpty($this->wopiToken);
|
|
}
|
|
|
|
|
|
/**
|
|
* @Given /^TemplateSource is set$/
|
|
*/
|
|
public function templatesourceIsSet() {
|
|
$this->wopiContext->checkfileinfoMatches('TemplateSource', '%wopi/template/' . $this->templates[0]['id'] . '\\?access_token%');
|
|
}
|
|
|
|
private function extractRichdocumentsFrontendContext($response) {
|
|
$contents = $response->getBody()->getContents();
|
|
$re = '/id="initial-state-richdocuments-([A-z]+)" value="(.*)"/m';
|
|
preg_match_all($re, $contents, $matches, PREG_SET_ORDER, 0);
|
|
$result = [];
|
|
foreach ($matches as $match) {
|
|
$result[$match[1]] = json_decode(base64_decode($match[2], true), true);
|
|
}
|
|
|
|
$document = $result['document'];
|
|
$this->fileIds[] = $document['fileId'];
|
|
$this->fileId = $document['fileId'];
|
|
$this->wopiToken = $document['token'];
|
|
$this->wopiContext->setWopiParameters($this->currentServer, $this->fileId, $this->wopiToken);
|
|
}
|
|
|
|
/**
|
|
* @When /^the guest updates the display name to "([^"]*)"$/
|
|
*/
|
|
public function updateTheGuestDisplayName($displayName) {
|
|
$this->serverContext->sendOCSRequest('POST', 'apps/richdocuments/api/v1/wopi/guestname', [
|
|
'access_token' => $this->wopiContext->getWopiToken(),
|
|
'guestName' => $displayName,
|
|
], [ 'auth' => null ]);
|
|
}
|
|
|
|
/**
|
|
* @Given /^as "([^"]*)" rename "([^"]*)" to "([^"]*)"$/
|
|
*/
|
|
public function renameFileTo($user, $file, $newName) {
|
|
$this->serverContext->usingWebAsUser($user);
|
|
$davClient = $this->filesContext->getSabreClient($user);
|
|
$path = $this->filesContext->makeSabrePath($user, $file);
|
|
$result = $davClient->propFind($path, ['{http://owncloud.org/ns}fileid']);
|
|
$fileId = $result['{http://owncloud.org/ns}fileid'];
|
|
|
|
$this->wopiContext->collaboraRenamesTo($fileId, $newName);
|
|
}
|
|
|
|
/**
|
|
* @When admin enables secure view
|
|
*/
|
|
public function enableSecureView(): void {
|
|
$this->serverContext->actAsAdmin(function () {
|
|
$watermarkKeysToEnable = [
|
|
'watermark_enabled',
|
|
'watermark_linkAll',
|
|
'watermark_shareRead',
|
|
];
|
|
|
|
foreach ($watermarkKeysToEnable as $configKey) {
|
|
$this->serverContext->sendOCSRequest(
|
|
'POST',
|
|
'apps/provisioning_api/api/v1/config/apps/files/' . $configKey,
|
|
['value' => 'yes'],
|
|
);
|
|
$this->serverContext->assertHttpStatusCode(200);
|
|
}
|
|
});
|
|
}
|
|
}
|