fix(dav): check the owner displayName scope before giving attribute

Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
pull/52535/head
skjnldsv 5 months ago committed by John Molakvoæ
parent 88aa80e847
commit 58aaddeca5
  1. 21
      apps/dav/lib/Connector/Sabre/FilesPlugin.php
  2. 2
      apps/dav/lib/Connector/Sabre/ServerFactory.php
  3. 2
      apps/dav/lib/Server.php
  4. 121
      apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
  5. 3
      apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php
  6. 6
      apps/files_sharing/src/views/FilesHeaderNoteToRecipient.vue

@ -11,6 +11,7 @@ use OC\AppFramework\Http\Request;
use OC\FilesMetadata\Model\FilesMetadata;
use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
use OCA\Files_Sharing\External\Mount as SharingExternalMount;
use OCP\Accounts\IAccountManager;
use OCP\Constants;
use OCP\Files\ForbiddenException;
use OCP\Files\IFilenameValidator;
@ -91,6 +92,7 @@ class FilesPlugin extends ServerPlugin {
private IPreview $previewManager,
private IUserSession $userSession,
private IFilenameValidator $validator,
private IAccountManager $accountManager,
private bool $isPublic = false,
private bool $downloadAttachment = true,
) {
@ -361,9 +363,26 @@ class FilesPlugin extends ServerPlugin {
$owner = $node->getOwner();
if (!$owner) {
return null;
} else {
}
// Get current user to see if we're in a public share or not
$user = $this->userSession->getUser();
// If the user is logged in, we can return the display name
if ($user !== null) {
return $owner->getDisplayName();
}
// Check if the user published their display name
$ownerAccount = $this->accountManager->getAccount($owner);
$ownerNameProperty = $ownerAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME);
// Since we are not logged in, we need to have at least the published scope
if ($ownerNameProperty->getScope() === IAccountManager::SCOPE_PUBLISHED) {
return $owner->getDisplayName();
}
return null;
});
$propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {

@ -14,6 +14,7 @@ use OCA\DAV\DAV\CustomPropertiesBackend;
use OCA\DAV\DAV\ViewOnlyPlugin;
use OCA\DAV\Files\BrowserErrorPagePlugin;
use OCA\Theming\ThemingDefaults;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
use OCP\Comments\ICommentsManager;
use OCP\EventDispatcher\IEventDispatcher;
@ -128,6 +129,7 @@ class ServerFactory {
$this->previewManager,
$this->userSession,
\OCP\Server::get(IFilenameValidator::class),
\OCP\Server::get(IAccountManager::class),
false,
!$this->config->getSystemValue('debug', false)
)

@ -64,6 +64,7 @@ use OCA\DAV\SystemTag\SystemTagPlugin;
use OCA\DAV\Upload\ChunkingPlugin;
use OCA\DAV\Upload\ChunkingV2Plugin;
use OCA\Theming\ThemingDefaults;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Utility\ITimeFactory;
@ -287,6 +288,7 @@ class Server {
\OCP\Server::get(IPreview::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(IFilenameValidator::class),
\OCP\Server::get(IAccountManager::class),
false,
$config->getSystemValueBool('debug', false) === false,
)

@ -7,12 +7,15 @@
*/
namespace OCA\DAV\Tests\unit\Connector\Sabre;
use OC\Accounts\Account;
use OC\Accounts\AccountProperty;
use OC\User\User;
use OCA\DAV\Connector\Sabre\Directory;
use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
use OCA\DAV\Connector\Sabre\File;
use OCA\DAV\Connector\Sabre\FilesPlugin;
use OCA\DAV\Connector\Sabre\Node;
use OCP\Accounts\IAccountManager;
use OCP\Files\FileInfo;
use OCP\Files\IFilenameValidator;
use OCP\Files\InvalidPathException;
@ -43,6 +46,7 @@ class FilesPluginTest extends TestCase {
private IPreview&MockObject $previewManager;
private IUserSession&MockObject $userSession;
private IFilenameValidator&MockObject $filenameValidator;
private IAccountManager&MockObject $accountManager;
private FilesPlugin $plugin;
protected function setUp(): void {
@ -57,6 +61,7 @@ class FilesPluginTest extends TestCase {
$this->previewManager = $this->createMock(IPreview::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->filenameValidator = $this->createMock(IFilenameValidator::class);
$this->accountManager = $this->createMock(IAccountManager::class);
$this->plugin = new FilesPlugin(
$this->tree,
@ -65,6 +70,7 @@ class FilesPluginTest extends TestCase {
$this->previewManager,
$this->userSession,
$this->filenameValidator,
$this->accountManager,
);
$response = $this->getMockBuilder(ResponseInterface::class)
@ -154,6 +160,13 @@ class FilesPluginTest extends TestCase {
->method('getDisplayName')
->willReturn('M. Foo');
$owner = $this->getMockBuilder(Account::class)
->disableOriginalConstructor()->getMock();
$this->accountManager->expects($this->once())
->method('getAccount')
->with($user)
->willReturn($owner);
$node->expects($this->once())
->method('getDirectDownload')
->willReturn(['url' => 'http://example.com/']);
@ -161,6 +174,18 @@ class FilesPluginTest extends TestCase {
->method('getOwner')
->willReturn($user);
$displayNameProp = $this->getMockBuilder(AccountProperty::class)
->disableOriginalConstructor()->getMock();
$owner
->expects($this->once())
->method('getProperty')
->with(IAccountManager::PROPERTY_DISPLAYNAME)
->willReturn($displayNameProp);
$displayNameProp
->expects($this->once())
->method('getScope')
->willReturn(IAccountManager::SCOPE_PUBLISHED);
$this->plugin->handleGetProperties(
$propFind,
$node
@ -179,6 +204,101 @@ class FilesPluginTest extends TestCase {
$this->assertEquals([], $propFind->get404Properties());
}
public function testGetDisplayNamePropertyWhenNotPublished(): void {
/** @var File|\PHPUnit\Framework\MockObject\MockObject $node */
$node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
$propFind = new PropFind(
'/dummyPath',
[
FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME,
],
0
);
$this->userSession->expects($this->once())
->method('getUser')
->willReturn(null);
$user = $this->getMockBuilder(User::class)
->disableOriginalConstructor()->getMock();
$user
->expects($this->never())
->method('getDisplayName');
$owner = $this->getMockBuilder(Account::class)
->disableOriginalConstructor()->getMock();
$this->accountManager->expects($this->once())
->method('getAccount')
->with($user)
->willReturn($owner);
$node->expects($this->once())
->method('getOwner')
->willReturn($user);
$displayNameProp = $this->getMockBuilder(AccountProperty::class)
->disableOriginalConstructor()->getMock();
$owner
->expects($this->once())
->method('getProperty')
->with(IAccountManager::PROPERTY_DISPLAYNAME)
->willReturn($displayNameProp);
$displayNameProp
->expects($this->once())
->method('getScope')
->willReturn(IAccountManager::SCOPE_PRIVATE);
$this->plugin->handleGetProperties(
$propFind,
$node
);
$this->assertEquals(null, $propFind->get(FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME));
}
public function testGetDisplayNamePropertyWhenNotPublishedButLoggedIn(): void {
/** @var File|\PHPUnit\Framework\MockObject\MockObject $node */
$node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
$propFind = new PropFind(
'/dummyPath',
[
FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME,
],
0
);
$user = $this->getMockBuilder(User::class)
->disableOriginalConstructor()->getMock();
$node->expects($this->once())
->method('getOwner')
->willReturn($user);
$loggedInUser = $this->getMockBuilder(User::class)
->disableOriginalConstructor()->getMock();
$this->userSession->expects($this->once())
->method('getUser')
->willReturn($loggedInUser);
$user
->expects($this->once())
->method('getDisplayName')
->willReturn('M. Foo');
$this->accountManager->expects($this->never())
->method('getAccount');
$this->plugin->handleGetProperties(
$propFind,
$node
);
$this->assertEquals('M. Foo', $propFind->get(FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME));
}
public function testGetPropertiesStorageNotAvailable(): void {
/** @var File|\PHPUnit\Framework\MockObject\MockObject $node */
$node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
@ -215,6 +335,7 @@ class FilesPluginTest extends TestCase {
$this->previewManager,
$this->userSession,
$this->filenameValidator,
$this->accountManager,
true,
);
$this->plugin->initialize($this->server);

@ -11,6 +11,7 @@ use OC\Files\View;
use OCA\DAV\Connector\Sabre\Directory;
use OCA\DAV\Connector\Sabre\FilesPlugin;
use OCA\DAV\Connector\Sabre\FilesReportPlugin as FilesReportPluginImplementation;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
use OCP\Files\File;
use OCP\Files\FileInfo;
@ -389,6 +390,7 @@ class FilesReportPluginTest extends \Test\TestCase {
->getMock();
$validator = $this->createMock(IFilenameValidator::class);
$accountManager = $this->createMock(IAccountManager::class);
$this->server->addPlugin(
new FilesPlugin(
@ -398,6 +400,7 @@ class FilesReportPluginTest extends \Test\TestCase {
$this->previewManager,
$this->createMock(IUserSession::class),
$validator,
$accountManager,
)
);
$this->plugin->initialize($this->server);

@ -6,7 +6,7 @@
<NcNoteCard v-if="note.length > 0"
class="note-to-recipient"
type="info">
<p v-if="user" class="note-to-recipient__heading">
<p v-if="displayName" class="note-to-recipient__heading">
{{ t('files_sharing', 'Note from') }}
<NcUserBubble :user="user.id" :display-name="user.displayName" />
</p>
@ -28,13 +28,13 @@ import NcUserBubble from '@nextcloud/vue/components/NcUserBubble'
const folder = ref<Folder>()
const note = computed<string>(() => folder.value?.attributes.note ?? '')
const displayName = computed<string>(() => folder.value?.attributes['owner-display-name'] ?? '')
const user = computed(() => {
const id = folder.value?.owner
const displayName = folder.value?.attributes?.['owner-display-name']
if (id !== getCurrentUser()?.uid) {
return {
id,
displayName,
displayName: displayName.value,
}
}
return null

Loading…
Cancel
Save