feat(sharing): Allow richdocuments to hide-download for public talk share links

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling
2025-05-15 15:58:25 +02:00
parent df1600bd91
commit 682ef4ec52
6 changed files with 52 additions and 1 deletions

View File

@ -12,6 +12,7 @@ use OCA\Circles\CirclesManager;
use OCA\DAV\CardDAV\PhotoCache;
use OCA\Talk\Chat\ChatManager;
use OCA\Talk\Events\MessageParseEvent;
use OCA\Talk\Events\OverwritePublicSharePropertiesEvent;
use OCA\Talk\Exceptions\ParticipantNotFoundException;
use OCA\Talk\Federation\Authenticator;
use OCA\Talk\GuestManager;
@ -26,6 +27,7 @@ use OCP\AppFramework\Services\IAppConfig;
use OCP\Comments\IComment;
use OCP\Comments\ICommentsManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\EventDispatcher\IEventListener;
use OCP\Federation\ICloudIdManager;
use OCP\Files\FileInfo;
@ -82,6 +84,7 @@ class SystemMessage implements IEventListener {
protected IURLGenerator $url,
protected FilesMetadataCache $metadataCache,
protected Authenticator $federationAuthenticator,
protected IEventDispatcher $dispatcher,
) {
}
@ -825,6 +828,7 @@ class SystemMessage implements IEventListener {
$node = $share->getNodeCacheEntry();
} else {
$node = $share->getNode();
$this->dispatcher->dispatchTyped(new OverwritePublicSharePropertiesEvent($share));
}
$name = $node->getName();
@ -854,6 +858,7 @@ class SystemMessage implements IEventListener {
'permissions' => (string)$node->getPermissions(),
'mimetype' => $node->getMimeType(),
'preview-available' => $isPreviewAvailable ? 'yes' : 'no',
'hide-download' => $share->getHideDownload() ? 'yes' : 'no',
];
// If a preview is available, check if we can get the dimensions of the file from the metadata API

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Events;
use OCP\EventDispatcher\Event;
use OCP\Share\IShare;
/**
* @internal
*/
class OverwritePublicSharePropertiesEvent extends Event {
public function __construct(
protected IShare $share,
) {
parent::__construct();
}
public function getShare(): IShare {
return $this->share;
}
}

View File

@ -121,7 +121,7 @@
</template>
{{ t('spreed', 'Go to file') }}
</NcActionLink>
<NcActionLink :href="linkToFileDownload" :download="messageFile.name">
<NcActionLink v-if="!hideDownloadOption" :href="linkToFileDownload" :download="messageFile.name">
<template #icon>
<IconDownload :size="20" />
</template>
@ -413,6 +413,7 @@ export default {
isCurrentUserOwnMessage,
isFileShare,
isFileShareWithoutCaption,
hideDownloadOption,
isConversationReadOnly,
isConversationModifiable,
} = useMessageInfo(message)
@ -426,6 +427,7 @@ export default {
isCurrentUserOwnMessage,
isFileShare,
isFileShareWithoutCaption,
hideDownloadOption,
isDeleteable,
isConversationReadOnly,
isConversationModifiable,

View File

@ -39,6 +39,7 @@ export function useMessageInfo(message = ref({})) {
isConversationReadOnly: computed(() => false),
isFileShareWithoutCaption: computed(() => false),
isFileShare: computed(() => false),
hideDownloadOption: computed(() => true),
remoteServer: computed(() => ''),
lastEditor: computed(() => ''),
actorDisplayName: computed(() => ''),
@ -80,6 +81,8 @@ export function useMessageInfo(message = ref({})) {
const isFileShare = computed(() => Object.keys(Object(message.value.messageParameters)).some(key => key.startsWith('file')))
const hideDownloadOption = computed(() => Object.values(Object(message.value.messageParameters)).some((value) => value.type === 'file' && value['hide-download'] === 'yes'))
const isFileShareWithoutCaption = computed(() => message.value.message === '{file}' && isFileShare.value)
const isDeleteable = computed(() =>
@ -134,6 +137,7 @@ export function useMessageInfo(message = ref({})) {
isConversationReadOnly,
isFileShareWithoutCaption,
isFileShare,
hideDownloadOption,
remoteServer,
lastEditor,
actorDisplayName,

View File

@ -24,6 +24,7 @@ use OCA\Talk\Share\Helper\FilesMetadataCache;
use OCA\Talk\Share\RoomShareProvider;
use OCP\AppFramework\Services\IAppConfig;
use OCP\Comments\IComment;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudId;
use OCP\Federation\ICloudIdManager;
use OCP\Files\Folder;
@ -59,6 +60,7 @@ class SystemMessageTest extends TestCase {
protected ICloudIdManager&MockObject $cloudIdManager;
protected FilesMetadataCache&MockObject $filesMetadataCache;
protected Authenticator&MockObject $federationAuthenticator;
protected IEventDispatcher&MockObject $dispatcher;
protected IL10N&MockObject $l;
public function setUp(): void {
@ -77,6 +79,7 @@ class SystemMessageTest extends TestCase {
$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
$this->filesMetadataCache = $this->createMock(FilesMetadataCache::class);
$this->federationAuthenticator = $this->createMock(Authenticator::class);
$this->dispatcher = $this->createMock(IEventDispatcher::class);
$this->l = $this->createMock(IL10N::class);
$this->l->method('t')
->willReturnCallback(function ($text, $parameters = []) {
@ -110,6 +113,7 @@ class SystemMessageTest extends TestCase {
$this->url,
$this->filesMetadataCache,
$this->federationAuthenticator,
$this->dispatcher,
])
->onlyMethods($methods)
->getMock();
@ -130,6 +134,7 @@ class SystemMessageTest extends TestCase {
$this->url,
$this->filesMetadataCache,
$this->federationAuthenticator,
$this->dispatcher,
);
}
@ -741,6 +746,7 @@ class SystemMessageTest extends TestCase {
'permissions' => '27',
'mimetype' => 'image/png',
'preview-available' => 'yes',
'hide-download' => 'no',
'width' => '1234',
'height' => '4567',
], self::invokePrivate($parser, 'getFileFromShare', [$room, $participant, '23', false]));
@ -817,6 +823,7 @@ class SystemMessageTest extends TestCase {
'permissions' => '27',
'mimetype' => 'image/png',
'preview-available' => 'yes',
'hide-download' => 'no',
'width' => '1234',
'height' => '4567',
'blurhash' => 'LEHV9uae2yk8pyo0adR*.7kCMdnj',
@ -897,6 +904,7 @@ class SystemMessageTest extends TestCase {
'permissions' => '27',
'mimetype' => 'httpd/unix-directory',
'preview-available' => 'no',
'hide-download' => 'no',
], self::invokePrivate($parser, 'getFileFromShare', [$room, $participant, '23', false]));
}
@ -982,6 +990,7 @@ class SystemMessageTest extends TestCase {
'permissions' => '27',
'mimetype' => 'application/octet-stream',
'preview-available' => 'no',
'hide-download' => 'no',
], self::invokePrivate($parser, 'getFileFromShare', [$room, $participant, '23', false]));
}

View File

@ -39,6 +39,10 @@ class EventDocumentationTest extends TestCase {
self::assertTrue(true, 'Deprecated event ' . $eventClass . ' does not have to be documented');
return;
}
if (is_string($classDocBlock) && str_contains($classDocBlock, '@internal')) {
self::assertTrue(true, 'Internal event ' . $eventClass . ' does not have to be documented');
return;
}
$docs = file_get_contents(__DIR__ . '/../../docs/events.md');
$eventIsDocumented = str_contains($docs, 'Before event: `' . $eventClass . '`')