diff --git a/apps/files_external/lib/Service/DBConfigService.php b/apps/files_external/lib/Service/DBConfigService.php index d6135ff88cccb..69c1b39b4d07a 100644 --- a/apps/files_external/lib/Service/DBConfigService.php +++ b/apps/files_external/lib/Service/DBConfigService.php @@ -384,7 +384,7 @@ public function setConfig(int $mountId, string $key, string $value): void { } } - public function setOption(int $mountId, string $key, string $value): void { + public function setOption(int $mountId, string $key, mixed $value): void { try { $builder = $this->connection->getQueryBuilder(); $builder->insert('external_options') diff --git a/apps/files_external/lib/Service/StoragesService.php b/apps/files_external/lib/Service/StoragesService.php index 545c1be0da68e..057c6ec1c71fc 100644 --- a/apps/files_external/lib/Service/StoragesService.php +++ b/apps/files_external/lib/Service/StoragesService.php @@ -36,6 +36,9 @@ * @psalm-import-type ExternalMountInfo from DBConfigService */ abstract class StoragesService { + // Default policy: once per request + private const DEFAULT_FILESYSTEM_CHECK_POLICY = 1; + public function __construct( protected BackendService $backendService, protected DBConfigService $dbConfig, @@ -60,13 +63,18 @@ protected function getStorageConfigFromDBMount(array $mount): ?StorageConfig { => $applicable['type'] === DBConfigService::APPLICABLE_TYPE_GROUP); $applicableGroups = array_map(static fn (array $applicable) => $applicable['value'], $applicableGroups); + $options = $mount['options']; + if (!array_key_exists('filesystem_check_changes', $options)) { + $options['filesystem_check_changes'] = self::DEFAULT_FILESYSTEM_CHECK_POLICY; + } + try { $config = $this->createStorage( $mount['mount_point'], $mount['storage_backend'], $mount['auth_backend'], $mount['config'], - $mount['options'], + $options, array_values($applicableUsers), array_values($applicableGroups), $mount['priority'] @@ -210,6 +218,11 @@ public function addStorage(StorageConfig $newStorage): StorageConfig { foreach ($newStorage->getBackendOptions() as $key => $value) { $this->dbConfig->setConfig($configId, $key, $value); } + + if (!array_key_exists('filesystem_check_changes', $newStorage->getMountOptions())) { + $newStorage->setMountOption('filesystem_check_changes', self::DEFAULT_FILESYSTEM_CHECK_POLICY); + } + foreach ($newStorage->getMountOptions() as $key => $value) { $this->dbConfig->setOption($configId, $key, $value); } diff --git a/apps/files_external/tests/Service/DBConfigServiceTest.php b/apps/files_external/tests/Service/DBConfigServiceTest.php index 989f8b918adf9..473b413e4c7a6 100644 --- a/apps/files_external/tests/Service/DBConfigServiceTest.php +++ b/apps/files_external/tests/Service/DBConfigServiceTest.php @@ -141,6 +141,28 @@ public function testSetConfigOverwrite(): void { $this->assertEquals(['foo' => 'qwerty', 'asd' => '1'], $mount['config']); } + #[DataProvider('nativeOptionValuesProvider')] + public function testSetOptionPreservesNativeTypes(mixed $value): void { + $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN); + + $this->dbConfig->setOption($id, 'test_option', $value); + + $mount = $this->dbConfig->getMountById($id); + + $this->assertSame($value, $mount['options']['test_option']); + } + + public static function nativeOptionValuesProvider(): array { + return [ + 'zero integer' => [0], + 'positive integer' => [1], + 'negative integer' => [-1], + 'float' => [1.5], + 'true' => [true], + 'false' => [false], + ]; + } + public function testSetOption(): void { $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN); $this->dbConfig->setOption($id, 'foo', 'bar'); diff --git a/apps/files_external/tests/Service/GlobalStoragesServiceTest.php b/apps/files_external/tests/Service/GlobalStoragesServiceTest.php index 59bab4d044487..8fca68df3b1eb 100644 --- a/apps/files_external/tests/Service/GlobalStoragesServiceTest.php +++ b/apps/files_external/tests/Service/GlobalStoragesServiceTest.php @@ -11,6 +11,7 @@ use OC\Files\Filesystem; use OCA\Files_External\MountConfig; +use OCA\Files_External\Service\DBConfigService; use OCA\Files_External\Service\GlobalStoragesService; #[\PHPUnit\Framework\Attributes\Group(name: 'DB')] @@ -126,6 +127,7 @@ public function testAddStorage($storageParams): void { $this->assertEquals($storage->getBackend(), $newStorage->getBackend()); $this->assertEquals($storage->getAuthMechanism(), $newStorage->getAuthMechanism()); $this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions()); + $this->assertSame(1, $newStorage->getMountOption('filesystem_check_changes')); $this->assertEquals($storage->getApplicableUsers(), $newStorage->getApplicableUsers()); $this->assertEquals($storage->getApplicableGroups(), $newStorage->getApplicableGroups()); $this->assertEquals($storage->getPriority(), $newStorage->getPriority()); @@ -135,6 +137,62 @@ public function testAddStorage($storageParams): void { $this->assertEquals($baseId + 1, $nextStorage->getId()); } + #[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'filesystemCheckChangesProvider')] + public function testAddStoragePreservesFilesystemCheckChanges(int $value): void { + $storage = $this->makeStorageConfig([ + 'mountPoint' => 'mountpoint-' . $value, + 'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB', + 'authMechanismIdentifier' => 'identifier:\Auth\Mechanism', + 'backendOptions' => [ + 'option1' => 'value1', + ], + 'applicableUsers' => [], + 'applicableGroups' => [], + 'mountOptions' => [ + 'filesystem_check_changes' => $value, + ], + ]); + + $newStorage = $this->service->addStorage($storage); + $reloadedStorage = $this->service->getStorage($newStorage->getId()); + + $this->assertSame( + $value, + $reloadedStorage->getMountOption('filesystem_check_changes') + ); + } + + public static function filesystemCheckChangesProvider(): array { + return [ + 'never' => [0], + 'once per request' => [1], + 'always' => [2], + ]; + } + + public function testLoadingMountWithoutFilesystemCheckChangesUsesCompatibilityDefault(): void { + $mountId = $this->dbConfig->addMount( + 'mountpoint', + 'identifier:\OCA\Files_External\Lib\Backend\SMB', + 'identifier:\Auth\Mechanism', + 100, + \OCA\Files_External\Service\DBConfigService::MOUNT_TYPE_ADMIN + ); + + $this->dbConfig->addApplicable( + $mountId, + DBConfigService::APPLICABLE_TYPE_GLOBAL, + null + ); + + $storage = $this->service->getStorage($mountId); + + $this->assertSame( + 1, + $storage->getMountOption('filesystem_check_changes') + ); + } + #[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'storageDataProvider')] public function testUpdateStorage($updatedStorageParams): void { $updatedStorage = $this->makeStorageConfig($updatedStorageParams); diff --git a/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php b/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php index 4a35796b97f46..a51dfa8f7c84f 100644 --- a/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php +++ b/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php @@ -267,6 +267,11 @@ public function testGetUniqueStorages( } } + public function testAddStoragePreservesFilesystemCheckChanges(): void { + // we don't test this here + $this->addToAssertionCount(1); + } + public function testGetStoragesBackendNotVisible(): void { // we don't test this here $this->addToAssertionCount(1);