Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/richdocuments.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2022-10-26 22:51:26 +0300
committerGitHub <noreply@github.com>2022-10-26 22:51:26 +0300
commitd03fa731c96c87708838c6b7318bc0ff560d3bba (patch)
treebd87038a8d554b5594c1fd0f5bf41f87358b5ad8
parent45fcd99ae300ca198cad79cbac7fd3355cfb2802 (diff)
parentfc9cbbd21d7d8680aa4830fb02c5529ceb8095f2 (diff)
Merge pull request #2579 from nextcloud/bugfix/watermark-preview
-rw-r--r--css/admin.scss2
-rw-r--r--css/templatePicker.scss2
-rw-r--r--lib/AppInfo/Application.php3
-rw-r--r--lib/Controller/SettingsController.php1
-rw-r--r--lib/Controller/WopiController.php70
-rw-r--r--lib/Listener/BeforeFetchPreviewListener.php82
-rw-r--r--lib/PermissionManager.php98
-rw-r--r--src/components/AdminSettings.vue30
-rw-r--r--tests/lib/PermissionManagerTest.php19
-rw-r--r--tests/psalm-baseline.xml27
-rw-r--r--tests/stub.phpstub30
11 files changed, 259 insertions, 105 deletions
diff --git a/css/admin.scss b/css/admin.scss
index a28b833a..d95e55e1 100644
--- a/css/admin.scss
+++ b/css/admin.scss
@@ -1,4 +1,4 @@
-@use "sass:math";
+@use 'sass:math';
.rd-settings-documentation {
max-width: 50em;
diff --git a/css/templatePicker.scss b/css/templatePicker.scss
index ee071863..b432d9a8 100644
--- a/css/templatePicker.scss
+++ b/css/templatePicker.scss
@@ -20,7 +20,7 @@
*
*/
- @use "sass:math";
+@use 'sass:math';
#template-picker {
.template-container:not(.hidden) {
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 19fd8e64..c61b92ad 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -27,6 +27,7 @@ namespace OCA\Richdocuments\AppInfo;
use OCA\Files_Sharing\Event\ShareLinkAccessedEvent;
use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Capabilities;
+use OCA\Richdocuments\Listener\BeforeFetchPreviewListener;
use OCA\Richdocuments\Listener\CSPListener;
use OCA\Richdocuments\Listener\LoadViewerListener;
use OCA\Richdocuments\Listener\ShareLinkListener;
@@ -52,6 +53,7 @@ use OCP\Files\Template\TemplateFileCreator;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IPreview;
+use OCP\Preview\BeforeFetchPreviewEvent;
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
class Application extends App implements IBootstrap {
@@ -70,6 +72,7 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(AddContentSecurityPolicyEvent::class, CSPListener::class);
$context->registerEventListener(LoadViewer::class, LoadViewerListener::class);
$context->registerEventListener(ShareLinkAccessedEvent::class, ShareLinkListener::class);
+ $context->registerEventListener(BeforeFetchPreviewEvent::class, BeforeFetchPreviewListener::class);
}
public function boot(IBootContext $context): void {
diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php
index 51210044..f9d99a73 100644
--- a/lib/Controller/SettingsController.php
+++ b/lib/Controller/SettingsController.php
@@ -237,6 +237,7 @@ class SettingsController extends Controller {
'watermark_enabled',
'watermark_shareAll',
'watermark_shareRead',
+ 'watermark_shareDisabledDownload',
'watermark_linkSecure',
'watermark_linkRead',
'watermark_linkAll',
diff --git a/lib/Controller/WopiController.php b/lib/Controller/WopiController.php
index 478a784c..62bb5e02 100644
--- a/lib/Controller/WopiController.php
+++ b/lib/Controller/WopiController.php
@@ -67,6 +67,7 @@ use OCP\Lock\LockedException;
use OCP\PreConditionNotMetException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager as IShareManager;
+use OCP\Share\IShare;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -234,7 +235,8 @@ class WopiController extends Controller {
$response['TemplateSaveAs'] = $file->getName();
}
- if ($this->shouldWatermark($isPublic, $wopi->getEditorUid(), $fileId, $wopi)) {
+ $share = $this->getShareForWopiToken($wopi);
+ if ($this->permissionManager->shouldWatermark($file, $wopi->getEditorUid(), $share)) {
$email = $user !== null && !$isPublic ? $user->getEMailAddress() : "";
$replacements = [
'userId' => $wopi->getEditorUid(),
@@ -318,62 +320,6 @@ class WopiController extends Controller {
return $response;
}
- private function shouldWatermark($isPublic, $userId, $fileId, Wopi $wopi) {
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_enabled', 'no') === 'no') {
- return false;
- }
-
- if ($isPublic) {
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkAll', 'no') === 'yes') {
- return true;
- }
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkRead', 'no') === 'yes' && !$wopi->getCanwrite()) {
- return true;
- }
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkSecure', 'no') === 'yes' && $wopi->getHideDownload()) {
- return true;
- }
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkTags', 'no') === 'yes') {
- $tags = $this->appConfig->getAppValueArray('watermark_linkTagsList');
- $fileTags = \OC::$server->getSystemTagObjectMapper()->getTagIdsForObjects([$fileId], 'files')[$fileId];
- foreach ($fileTags as $tagId) {
- if (in_array($tagId, $tags, true)) {
- return true;
- }
- }
- }
- } else {
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_shareAll', 'no') === 'yes') {
- $files = $this->rootFolder->getUserFolder($userId)->getById($fileId);
- if (count($files) !== 0 && $files[0]->getOwner()->getUID() !== $userId) {
- return true;
- }
- }
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_shareRead', 'no') === 'yes' && !$wopi->getCanwrite()) {
- return true;
- }
- }
- if ($userId !== null && $this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_allGroups', 'no') === 'yes') {
- $groups = $this->appConfig->getAppValueArray('watermark_allGroupsList');
- foreach ($groups as $group) {
- if (\OC::$server->getGroupManager()->isInGroup($userId, $group)) {
- return true;
- }
- }
- }
- if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_allTags', 'no') === 'yes') {
- $tags = $this->appConfig->getAppValueArray('watermark_allTagsList');
- $fileTags = \OC::$server->getSystemTagObjectMapper()->getTagIdsForObjects([$fileId], 'files')[$fileId];
- foreach ($fileTags as $tagId) {
- if (in_array($tagId, $tags, true)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
/**
* Given an access token and a fileId, returns the contents of the file.
* Expects a valid token in access_token parameter.
@@ -842,6 +788,7 @@ class WopiController extends Controller {
* @throws ShareNotFound
*/
private function getFileForWopiToken(Wopi $wopi) {
+ $this->userScopeService->setUserScope($wopi->getEditorUid());
if (!empty($wopi->getShare())) {
$share = $this->shareManager->getShareByToken($wopi->getShare());
$node = $share->getNode();
@@ -875,6 +822,15 @@ class WopiController extends Controller {
return array_shift($files);
}
+ private function getShareForWopiToken(Wopi $wopi): ?IShare {
+ try {
+ return $wopi->getShare() ? $this->shareManager->getShareByToken($wopi->getShare()) : null;
+ } catch (ShareNotFound $e) {
+ }
+
+ return null;
+ }
+
/**
* Endpoint to return the template file that is requested by collabora to create a new document
*
diff --git a/lib/Listener/BeforeFetchPreviewListener.php b/lib/Listener/BeforeFetchPreviewListener.php
new file mode 100644
index 00000000..20163f15
--- /dev/null
+++ b/lib/Listener/BeforeFetchPreviewListener.php
@@ -0,0 +1,82 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+namespace OCA\Richdocuments\Listener;
+
+use OCA\Files_Sharing\SharedStorage;
+use OCA\Richdocuments\PermissionManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Files\NotFoundException;
+use OCP\IRequest;
+use OCP\IUserSession;
+use OCP\Preview\BeforeFetchPreviewEvent;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+
+class BeforeFetchPreviewListener implements IEventListener {
+ private PermissionManager $permissionManager;
+ private IUserSession $userSession;
+ private IRequest $request;
+ private IManager $shareManager;
+
+ public function __construct(PermissionManager $permissionManager, IUserSession $userSession, IRequest $request, IManager $shareManager) {
+ $this->permissionManager = $permissionManager;
+ $this->userSession = $userSession;
+ $this->request = $request;
+ $this->shareManager = $shareManager;
+ }
+
+ public function handle(Event $event): void {
+ if (!$event instanceof BeforeFetchPreviewEvent) {
+ return;
+ }
+ $shareToken = $this->request->getParam('token');
+
+ $share = null;
+
+ // Get share for internal shares
+ $storage = $event->getNode()->getStorage();
+ if (!$shareToken && $storage->instanceOfStorage(SharedStorage::class)) {
+ if (method_exists(IShare::class, 'getAttributes')) {
+ /** @var SharedStorage $storage */
+ $share = $storage->getShare();
+ }
+ }
+
+ // Get different share for public previews as the share from the node is only set for mounted shares
+ try {
+ $share = $shareToken ? $this->shareManager->getShareByToken($shareToken) : $share;
+ } catch (ShareNotFound $e) {
+ }
+
+ $userId = $this->userSession->getUser() ? $this->userSession->getUser()->getUID() : null;
+ if ($this->permissionManager->shouldWatermark($event->getNode(), $userId, $share)) {
+ throw new NotFoundException();
+ }
+ }
+}
diff --git a/lib/PermissionManager.php b/lib/PermissionManager.php
index a509dc81..752a3618 100644
--- a/lib/PermissionManager.php
+++ b/lib/PermissionManager.php
@@ -23,26 +23,38 @@ declare(strict_types=1);
namespace OCA\Richdocuments;
+use OCP\Constants;
+use OCP\Files\Node;
+use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\IUserSession;
+use OCP\Share\IAttributes;
+use OCP\Share\IShare;
+use OCP\SystemTag\ISystemTagObjectMapper;
class PermissionManager {
- private AppConfig $config;
+ private AppConfig $appConfig;
+ private IConfig $config;
private IGroupManager $groupManager;
private IUserManager $userManager;
private IUserSession $userSession;
+ private ISystemTagObjectMapper $systemTagObjectMapper;
public function __construct(
- AppConfig $config,
- IGroupManager $groupManager,
- IUserManager $userManager,
- IUserSession $userSession
+ AppConfig $appConfig,
+ IConfig $config,
+ IGroupManager $groupManager,
+ IUserManager $userManager,
+ IUserSession $userSession,
+ ISystemTagObjectMapper $systemTagObjectMapper
) {
+ $this->appConfig = $appConfig;
$this->config = $config;
$this->groupManager = $groupManager;
$this->userManager = $userManager;
$this->userSession = $userSession;
+ $this->systemTagObjectMapper = $systemTagObjectMapper;
}
private function userMatchesGroupList(?string $userId = null, ?array $groupList = []): bool {
@@ -75,7 +87,7 @@ class PermissionManager {
}
public function isEnabledForUser(string $userId = null): bool {
- if ($this->userMatchesGroupList($userId, $this->config->getUseGroups())) {
+ if ($this->userMatchesGroupList($userId, $this->appConfig->getUseGroups())) {
return true;
}
@@ -83,7 +95,7 @@ class PermissionManager {
}
public function userCanEdit(string $userId = null): bool {
- if ($this->userMatchesGroupList($userId, $this->config->getEditGroups())) {
+ if ($this->userMatchesGroupList($userId, $this->appConfig->getEditGroups())) {
return true;
}
@@ -91,10 +103,80 @@ class PermissionManager {
}
public function userIsFeatureLocked(string $userId = null): bool {
- if ($this->config->isReadOnlyFeatureLocked() && !$this->userCanEdit($userId)) {
+ if ($this->appConfig->isReadOnlyFeatureLocked() && !$this->userCanEdit($userId)) {
return true;
}
return false;
}
+
+ public function shouldWatermark(Node $node, ?string $userId = null, ?IShare $share = null): bool {
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_enabled', 'no') === 'no') {
+ return false;
+ }
+
+ $fileId = $node->getId();
+
+ $isUpdatable = $node->isUpdateable() && (!$share || $share->getPermissions() & Constants::PERMISSION_UPDATE);
+
+ $hasShareAttributes = $share && method_exists($share, 'getAttributes') && $share->getAttributes() instanceof IAttributes;
+ $isDisabledDownload = $hasShareAttributes && $share->getAttributes()->getAttribute('permissions', 'download') === false;
+ $isHideDownload = $share && $share->getHideDownload();
+ $isSecureView = $isDisabledDownload || $isHideDownload;
+
+ if ($share && $share->getShareType() === IShare::TYPE_LINK) {
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkAll', 'no') === 'yes') {
+ return true;
+ }
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkRead', 'no') === 'yes' && !$isUpdatable) {
+ return true;
+ }
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkSecure', 'no') === 'yes' && $isSecureView) {
+ return true;
+ }
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_linkTags', 'no') === 'yes') {
+ $tags = $this->appConfig->getAppValueArray('watermark_linkTagsList');
+ $fileTags = $this->systemTagObjectMapper->getTagIdsForObjects([$fileId], 'files')[$fileId];
+ foreach ($fileTags as $tagId) {
+ if (in_array($tagId, $tags, true)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_shareAll', 'no') === 'yes') {
+ if ($node->getOwner()->getUID() !== $userId) {
+ return true;
+ }
+ }
+
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_shareRead', 'no') === 'yes' && !$isUpdatable) {
+ return true;
+ }
+
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_shareDisabledDownload', 'no') === 'yes' && $isDisabledDownload) {
+ return true;
+ }
+
+ if ($userId !== null && $this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_allGroups', 'no') === 'yes') {
+ $groups = $this->appConfig->getAppValueArray('watermark_allGroupsList');
+ foreach ($groups as $group) {
+ if ($this->groupManager->isInGroup($userId, $group)) {
+ return true;
+ }
+ }
+ }
+ if ($this->config->getAppValue(AppConfig::WATERMARK_APP_NAMESPACE, 'watermark_allTags', 'no') === 'yes') {
+ $tags = $this->appConfig->getAppValueArray('watermark_allTagsList');
+ $fileTags = $this->systemTagObjectMapper->getTagIdsForObjects([$fileId], 'files')[$fileId];
+ foreach ($fileTags as $tagId) {
+ if (in_array($tagId, $tags, true)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/components/AdminSettings.vue b/src/components/AdminSettings.vue
index 58bb8742..d7ecb3c4 100644
--- a/src/components/AdminSettings.vue
+++ b/src/components/AdminSettings.vue
@@ -298,6 +298,12 @@
<div v-if="isSetup" id="secure-view-settings" class="section">
<h2>{{ t('richdocuments', 'Secure view settings') }}</h2>
<p>{{ t('richdocuments', 'Secure view enables you to secure documents by embedding a watermark') }}</p>
+ <ul>
+ <li>{{ t('richdocuments', 'The settings only apply to compatible office files that are opened in Nextcloud Office') }}</li>
+ <li>{{ t('richdocuments', 'The following options within Nextcloud Office will be disabled: Copy, Download, Export, Print') }}</li>
+ <li>{{ t('richdocuments', 'Files may still be downloadable through Nextcloud unless restricted otherwise through sharing or access control settings') }}</li>
+ <li>{{ t('richdocuments', 'Previews will be blocked for watermarked files to not leak the first page of documents') }}</li>
+ </ul>
<SettingsCheckbox v-model="settings.watermark.enabled"
:label="t('richdocuments', 'Enable watermarking')"
hint=""
@@ -335,6 +341,12 @@
hint=""
:disabled="updating"
@input="update" />
+ <SettingsCheckbox v-if="!settings.watermark.shareAll"
+ v-model="settings.watermark.shareDisabledDownload"
+ :label="t('richdocuments', 'Show watermark for shares without download permission')"
+ hint=""
+ :disabled="updating"
+ @input="update" />
<h3>Link shares</h3>
<SettingsCheckbox v-model="settings.watermark.linkAll"
@@ -772,18 +784,18 @@ export default {
margin-left: 25px;
&:not(.multiselect) {
margin-top: 10px;
- font-style: italic;
}
- ul {
- margin-bottom: 15px;
- }
+ }
- li {
- list-style: disc;
- padding: 3px;
- margin-left: 20px;
- }
+ ul {
+ margin-bottom: 15px;
+ }
+
+ li {
+ list-style: disc;
+ padding: 3px;
+ margin-left: 20px;
}
.modal__content {
diff --git a/tests/lib/PermissionManagerTest.php b/tests/lib/PermissionManagerTest.php
index a48d7478..de830b93 100644
--- a/tests/lib/PermissionManagerTest.php
+++ b/tests/lib/PermissionManagerTest.php
@@ -28,10 +28,13 @@ use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
+use OCP\SystemTag\ISystemTagObjectMapper;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class PermissionManagerTest extends TestCase {
+ /** @var AppConfig|MockObject */
+ private $appConfig;
/** @var IConfig|MockObject */
private $config;
/** @var IGroupManager|MockObject */
@@ -45,15 +48,17 @@ class PermissionManagerTest extends TestCase {
public function setUp(): void {
parent::setUp();
- $this->config = $this->createMock(AppConfig::class);
+ $this->appConfig = $this->createMock(AppConfig::class);
+ $this->config = $this->createMock(IConfig::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->userSession = $this->createMock(IUserSession::class);
- $this->permissionManager = new PermissionManager($this->config, $this->groupManager, $this->userManager, $this->userSession);
+ $this->systemTagMapper = $this->createMock(ISystemTagObjectMapper::class);
+ $this->permissionManager = new PermissionManager($this->appConfig, $this->config, $this->groupManager, $this->userManager, $this->userSession, $this->systemTagMapper);
}
public function testIsEnabledForUserEnabledNoRestrictions(): void {
- $this->config
+ $this->appConfig
->expects($this->once())
->method('getUseGroups')
->willReturn(null);
@@ -77,7 +82,7 @@ class PermissionManagerTest extends TestCase {
/** @dataProvider dataGroupMatchGroups */
public function testEditGroups($editGroups, $userGroups, $result): void {
$userMock = $this->createMock(IUser::class);
- $this->config->expects($this->any())
+ $this->appConfig->expects($this->any())
->method('getEditGroups')
->willReturn($editGroups);
$this->userManager->expects($this->any())
@@ -93,7 +98,7 @@ class PermissionManagerTest extends TestCase {
/** @dataProvider dataGroupMatchGroups */
public function testUseGroups($editGroups, $userGroups, $result): void {
$userMock = $this->createMock(IUser::class);
- $this->config->expects($this->any())
+ $this->appConfig->expects($this->any())
->method('getUseGroups')
->willReturn($editGroups);
$this->userManager->expects($this->any())
@@ -109,10 +114,10 @@ class PermissionManagerTest extends TestCase {
/** @dataProvider dataGroupMatchGroups */
public function testFeatureLock($editGroups, $userGroups, $result): void {
$userMock = $this->createMock(IUser::class);
- $this->config->expects($this->any())
+ $this->appConfig->expects($this->any())
->method('getEditGroups')
->willReturn($editGroups);
- $this->config->expects($this->any())
+ $this->appConfig->expects($this->any())
->method('isReadOnlyFeatureLocked')
->willReturn(true);
$this->userManager->expects($this->any())
diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml
index 87c7e3dd..bf7f35c2 100644
--- a/tests/psalm-baseline.xml
+++ b/tests/psalm-baseline.xml
@@ -22,6 +22,9 @@
<code>OpenDocument</code>
<code>Pdf</code>
</MissingDependency>
+ <UndefinedClass occurrences="1">
+ <code>BeforeFetchPreviewEvent</code>
+ </UndefinedClass>
</file>
<file src="lib/Command/ActivateConfig.php">
<RedundantCondition occurrences="1">
@@ -76,24 +79,16 @@
<code>$item-&gt;getId()</code>
<code>$node-&gt;getId()</code>
</InvalidScalarArgument>
- <MissingDependency occurrences="7">
- <code>$this-&gt;rootFolder</code>
+ <MissingDependency occurrences="5">
<code>$this-&gt;rootFolder</code>
<code>$this-&gt;rootFolder</code>
<code>$this-&gt;rootFolder</code>
- <code>BeforeFederationRedirectEvent</code>
<code>IRootFolder</code>
<code>IRootFolder</code>
</MissingDependency>
<RedundantCondition occurrences="1">
<code>$app !== ''</code>
</RedundantCondition>
- <UndefinedClass occurrences="1">
- <code>\OCA\Files_Sharing\External\Storage</code>
- </UndefinedClass>
- <UndefinedInterfaceMethod occurrences="1">
- <code>getRemote</code>
- </UndefinedInterfaceMethod>
</file>
<file src="lib/Controller/OCSController.php">
<MissingDependency occurrences="4">
@@ -129,9 +124,7 @@
</UndefinedDocblockClass>
</file>
<file src="lib/Controller/WopiController.php">
- <MissingDependency occurrences="13">
- <code>$this-&gt;rootFolder</code>
- <code>$this-&gt;rootFolder</code>
+ <MissingDependency occurrences="11">
<code>$this-&gt;rootFolder</code>
<code>$this-&gt;rootFolder</code>
<code>$this-&gt;rootFolder</code>
@@ -159,6 +152,16 @@
<code>$time</code>
</InvalidScalarArgument>
</file>
+ <file src="lib/Listener/BeforeFetchPreviewListener.php">
+ <UndefinedClass occurrences="1">
+ <code>BeforeFetchPreviewEvent</code>
+ </UndefinedClass>
+ </file>
+ <file src="lib/PermissionManager.php">
+ <RedundantCondition occurrences="1">
+ <code>$share &amp;&amp; method_exists($share, 'getAttributes')</code>
+ </RedundantCondition>
+ </file>
<file src="lib/Preview/MSExcel.php">
<MissingDependency occurrences="1">
<code>Office</code>
diff --git a/tests/stub.phpstub b/tests/stub.phpstub
index 8b53b34d..e58a0f07 100644
--- a/tests/stub.phpstub
+++ b/tests/stub.phpstub
@@ -3,31 +3,40 @@
declare(strict_types=1);
namespace OCA\Federation {
- class TrustedServers {
- public function getServers() {}
- public function isTrustedServer($domainWithPort) {}
- }
+ class TrustedServers {
+ public function getServers() {
+ }
+ public function isTrustedServer($domainWithPort) {
+ }
+ }
}
namespace OCA\Viewer\Event {
- class LoadViewer extends \OCP\EventDispatcher\Event {}
+ class LoadViewer extends \OCP\EventDispatcher\Event {
+ }
}
namespace Doctrine\DBAL\Platforms {
- class SqlitePlatform {}
+ class SqlitePlatform {
+ }
}
namespace OCA\Files_Sharing {
+ use OCP\Files\Storage\IStorage;
use \OCP\Share\IShare;
- class SharedStorage {
- public function getShare(): IShare {}
+
+ abstract class SharedStorage implements IStorage {
+ public function getShare(): IShare {
+ }
}
}
namespace OCA\Files_Sharing\Event {
use \OCP\Share\IShare;
+
class ShareLinkAccessedEvent extends \OCP\EventDispatcher\Event {
- public function __construct(IShare $share, string $step = '', int $errorCode = 200, string $errorMessage = '') {}
+ public function __construct(IShare $share, string $step = '', int $errorCode = 200, string $errorMessage = '') {
+ }
public function getShare(): IShare {
}
@@ -44,5 +53,6 @@ namespace OCA\Files_Sharing\Event {
}
class OC_Helper {
- public static function getFileTemplateManager() {}
+ public static function getFileTemplateManager() {
+ }
}