Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add appconfig to disable fixed userfolder permissions optimization #51145

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion apps/files_external/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This application enables administrators to configure connections to external sto

External storage can be configured using the GUI or at the command line. This second option provides the administration with more flexibility for configuring bulk external storage mounts and setting mount priorities. More information is available in the external storage GUI documentation and the external storage Configuration File documentation.
</description>
<version>1.24.0</version>
<version>1.25.0</version>
<licence>agpl</licence>
<author>Robin Appelman</author>
<author>Michael Gapczynski</author>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
'OCA\\Files_External\\Migration\\Version1011Date20200630192246' => $baseDir . '/../lib/Migration/Version1011Date20200630192246.php',
'OCA\\Files_External\\Migration\\Version1015Date20211104103506' => $baseDir . '/../lib/Migration/Version1015Date20211104103506.php',
'OCA\\Files_External\\Migration\\Version1016Date20220324154536' => $baseDir . '/../lib/Migration/Version1016Date20220324154536.php',
'OCA\\Files_External\\Migration\\Version1025Date20250228162604' => $baseDir . '/../lib/Migration/Version1025Date20250228162604.php',
'OCA\\Files_External\\Migration\\Version22000Date20210216084416' => $baseDir . '/../lib/Migration/Version22000Date20210216084416.php',
'OCA\\Files_External\\MountConfig' => $baseDir . '/../lib/MountConfig.php',
'OCA\\Files_External\\NotFoundException' => $baseDir . '/../lib/NotFoundException.php',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class ComposerStaticInitFiles_External
'OCA\\Files_External\\Migration\\Version1011Date20200630192246' => __DIR__ . '/..' . '/../lib/Migration/Version1011Date20200630192246.php',
'OCA\\Files_External\\Migration\\Version1015Date20211104103506' => __DIR__ . '/..' . '/../lib/Migration/Version1015Date20211104103506.php',
'OCA\\Files_External\\Migration\\Version1016Date20220324154536' => __DIR__ . '/..' . '/../lib/Migration/Version1016Date20220324154536.php',
'OCA\\Files_External\\Migration\\Version1025Date20250228162604' => __DIR__ . '/..' . '/../lib/Migration/Version1025Date20250228162604.php',
'OCA\\Files_External\\Migration\\Version22000Date20210216084416' => __DIR__ . '/..' . '/../lib/Migration/Version22000Date20210216084416.php',
'OCA\\Files_External\\MountConfig' => __DIR__ . '/..' . '/../lib/MountConfig.php',
'OCA\\Files_External\\NotFoundException' => __DIR__ . '/..' . '/../lib/NotFoundException.php',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Files_External\Migration;

use Closure;
use OCA\Files_External\Service\DBConfigService;
use OCP\DB\ISchemaWrapper;
use OCP\IAppConfig;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

/**
* Check for any external storage overwriting the home folder
*/
class Version1025Date20250228162604 extends SimpleMigrationStep {
public function __construct(
private DBConfigService $dbConfig,
private IAppConfig $appConfig,
) {
}


/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
if ($this->dbConfig->hasHomeFolderOverwriteMount()) {
$this->appConfig->setValueBool('files', 'homeFolderOverwritten', true);
}
}
}
30 changes: 23 additions & 7 deletions apps/files_external/lib/Service/DBConfigService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace OCA\Files_External\Service;

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
Expand Down Expand Up @@ -63,16 +64,16 @@ public function getMountsForUser($userId, $groupIds) {
->where($builder->expr()->orX(
$builder->expr()->andX( // global mounts
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GLOBAL, IQueryBuilder::PARAM_INT)),
$builder->expr()->isNull('a.value')
$builder->expr()->isNull('a.value'),
),
$builder->expr()->andX( // mounts for user
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_USER, IQueryBuilder::PARAM_INT)),
$builder->expr()->eq('a.value', $builder->createNamedParameter($userId))
$builder->expr()->eq('a.value', $builder->createNamedParameter($userId)),
),
$builder->expr()->andX( // mounts for group
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GROUP, IQueryBuilder::PARAM_INT)),
$builder->expr()->in('a.value', $builder->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY))
)
$builder->expr()->in('a.value', $builder->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)),
),
));

return $this->getMountsFromQuery($query);
Expand All @@ -93,8 +94,8 @@ protected function modifyMountsOnDelete(string $applicableId, int $applicableTyp
->leftJoin('a', 'external_applicable', 'b', $builder->expr()->eq('a.mount_id', 'b.mount_id'))
->where($builder->expr()->andX(
$builder->expr()->eq('b.type', $builder->createNamedParameter($applicableType, IQueryBuilder::PARAM_INT)),
$builder->expr()->eq('b.value', $builder->createNamedParameter($applicableId))
)
$builder->expr()->eq('b.value', $builder->createNamedParameter($applicableId)),
),
)
->groupBy(['a.mount_id']);
$stmt = $query->executeQuery();
Expand Down Expand Up @@ -226,7 +227,7 @@ public function addMount($mountPoint, $storageBackend, $authBackend, $priority,
'storage_backend' => $builder->createNamedParameter($storageBackend, IQueryBuilder::PARAM_STR),
'auth_backend' => $builder->createNamedParameter($authBackend, IQueryBuilder::PARAM_STR),
'priority' => $builder->createNamedParameter($priority, IQueryBuilder::PARAM_INT),
'type' => $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)
'type' => $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT),
]);
$query->executeStatement();
return $query->getLastInsertId();
Expand Down Expand Up @@ -497,4 +498,19 @@ private function decryptValue($value) {
return $value;
}
}

/**
* Check if any mountpoint is configured that overwrite the home folder
*
* @return bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary?

*/
public function hasHomeFolderOverwriteMount(): bool {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('mount_id')
->from('external_mounts')
->where($builder->expr()->eq('mount_point', $builder->createNamedParameter('/')))
->setMaxResults(1);
$result = $query->executeQuery();
return (bool)$result->fetchColumn();
}
}
6 changes: 6 additions & 0 deletions apps/files_external/lib/Service/StoragesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Events\InvalidateMountCacheEvent;
use OCP\Files\StorageNotAvailableException;
use OCP\IAppConfig;
use OCP\Server;
use OCP\Util;
use Psr\Log\LoggerInterface;
Expand All @@ -39,6 +40,7 @@ public function __construct(
protected DBConfigService $dbConfig,
protected IUserMountCache $userMountCache,
protected IEventDispatcher $eventDispatcher,
protected IAppConfig $appConfig,
) {
}

Expand Down Expand Up @@ -424,6 +426,10 @@ public function updateStorage(StorageConfig $updatedStorage) {
}
}

if ($this->dbConfig->hasHomeFolderOverwriteMount()) {
$this->appConfig->setValueBool('files', 'homeFolderOverwritten', true);
}

return $this->getStorage($id);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use OCA\Files_External\Lib\StorageConfig;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\IUserMountCache;
use OCP\IAppConfig;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserSession;
Expand All @@ -35,8 +36,9 @@ public function __construct(
protected IGroupManager $groupManager,
IUserMountCache $userMountCache,
IEventDispatcher $eventDispatcher,
IAppConfig $appConfig,
) {
parent::__construct($backendService, $dbConfig, $userMountCache, $eventDispatcher);
parent::__construct($backendService, $dbConfig, $userMountCache, $eventDispatcher, $appConfig);
$this->userSession = $userSession;
}

Expand Down
4 changes: 3 additions & 1 deletion apps/files_external/lib/Service/UserStoragesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use OCA\Files_External\NotFoundException;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\IUserMountCache;
use OCP\IAppConfig;
use OCP\IUserSession;

/**
Expand All @@ -36,9 +37,10 @@ public function __construct(
IUserSession $userSession,
IUserMountCache $userMountCache,
IEventDispatcher $eventDispatcher,
IAppConfig $appConfig,
) {
$this->userSession = $userSession;
parent::__construct($backendService, $dbConfig, $userMountCache, $eventDispatcher);
parent::__construct($backendService, $dbConfig, $userMountCache, $eventDispatcher, $appConfig);
}

protected function readDBConfig() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class GlobalStoragesServiceTest extends StoragesServiceTest {
protected function setUp(): void {
parent::setUp();
$this->service = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache, $this->eventDispatcher);
$this->service = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache, $this->eventDispatcher, $this->appConfig);
}

protected function tearDown(): void {
Expand Down
6 changes: 6 additions & 0 deletions apps/files_external/tests/Service/StoragesServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorage;
use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IUser;
Expand Down Expand Up @@ -86,6 +87,10 @@ abstract class StoragesServiceTest extends \Test\TestCase {
* @var \PHPUnit\Framework\MockObject\MockObject|IEventDispatcher
*/
protected IEventDispatcher $eventDispatcher;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|IAppConfig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @var \PHPUnit\Framework\MockObject\MockObject|IAppConfig
* @var \PHPUnit\Framework\MockObject\MockObject&IAppConfig

*/
protected IAppConfig $appConfig;

protected function setUp(): void {
parent::setUp();
Expand All @@ -100,6 +105,7 @@ protected function setUp(): void {

$this->mountCache = $this->createMock(IUserMountCache::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->appConfig = $this->createMock(IAppConfig::class);

// prepare BackendService mock
$this->backendService =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ protected function setUp(): void {
$this->groupManager,
$this->mountCache,
$this->eventDispatcher,
$this->appConfig,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class UserStoragesServiceTest extends StoragesServiceTest {
protected function setUp(): void {
parent::setUp();

$this->globalStoragesService = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache, $this->eventDispatcher);
$this->globalStoragesService = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache, $this->eventDispatcher, $this->appConfig);

$this->userId = $this->getUniqueID('user_');
$this->createUser($this->userId, $this->userId);
Expand All @@ -50,7 +50,7 @@ protected function setUp(): void {
->method('getUser')
->willReturn($this->user);

$this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession, $this->mountCache, $this->eventDispatcher);
$this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession, $this->mountCache, $this->eventDispatcher, $this->appConfig);
}

private function makeTestStorageData() {
Expand Down
20 changes: 12 additions & 8 deletions lib/private/Files/Node/LazyUserFolder.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,20 @@ class LazyUserFolder extends LazyFolder {
private string $path;
private IMountManager $mountManager;

public function __construct(IRootFolder $rootFolder, IUser $user, IMountManager $mountManager) {
public function __construct(IRootFolder $rootFolder, IUser $user, IMountManager $mountManager, bool $useDefaultPermissions = true) {
$this->user = $user;
$this->mountManager = $mountManager;
$this->path = '/' . $user->getUID() . '/files';
$data = [
'path' => $this->path,
// Sharing user root folder is not allowed
'type' => FileInfo::TYPE_FOLDER,
'mimetype' => FileInfo::MIMETYPE_FOLDER,
];
if ($useDefaultPermissions) {
$data['permissions'] = Constants::PERMISSION_ALL ^ Constants::PERMISSION_SHARE;
}

parent::__construct($rootFolder, function () use ($user): Folder {
try {
$node = $this->getRootFolder()->get($this->path);
Expand All @@ -44,13 +54,7 @@ public function __construct(IRootFolder $rootFolder, IUser $user, IMountManager
}
return $this->getRootFolder()->newFolder($this->path);
}
}, [
'path' => $this->path,
// Sharing user root folder is not allowed
'permissions' => Constants::PERMISSION_ALL ^ Constants::PERMISSION_SHARE,
'type' => FileInfo::TYPE_FOLDER,
'mimetype' => FileInfo::MIMETYPE_FOLDER,
]);
}, $data);
}

public function getMountPoint() {
Expand Down
6 changes: 5 additions & 1 deletion lib/private/Files/Node/Root.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use OCP\Files\Node as INode;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\IAppConfig;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IUser;
Expand Down Expand Up @@ -60,6 +61,7 @@ class Root extends Folder implements IRootFolder {
private IUserManager $userManager;
private IEventDispatcher $eventDispatcher;
private ICache $pathByIdCache;
private bool $homeFolderOverwritten = false;

/**
* @param Manager $manager
Expand All @@ -75,6 +77,7 @@ public function __construct(
IUserManager $userManager,
IEventDispatcher $eventDispatcher,
ICacheFactory $cacheFactory,
IAppConfig $appConfig,
) {
parent::__construct($this, $view, '');
$this->mountManager = $manager;
Expand All @@ -88,6 +91,7 @@ public function __construct(
$this->userFolderCache = new CappedMemoryCache();
});
$this->pathByIdCache = $cacheFactory->createLocal('path-by-id');
$this->homeFolderOverwritten = $appConfig->getValueBool('files', 'homeFolderOverwritten');
}

/**
Expand Down Expand Up @@ -367,7 +371,7 @@ public function getUserFolder($userId) {
$folder = $this->newFolder('/' . $userId . '/files');
}
} else {
$folder = new LazyUserFolder($this, $userObject, $this->mountManager);
$folder = new LazyUserFolder($this, $userObject, $this->mountManager, !$this->homeFolderOverwritten);
}

$this->userFolderCache->set($userId, $folder);
Expand Down
1 change: 1 addition & 0 deletions lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ public function __construct($webRoot, \OC\Config $config) {
$this->get(IUserManager::class),
$this->get(IEventDispatcher::class),
$this->get(ICacheFactory::class),
$this->get(IAppConfig::class),
);

$previewConnector = new \OC\Preview\WatcherConnector(
Expand Down
Loading
Loading