feat(files_external): support lexicon

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
pull/52621/head
Maxence Lange 2025-05-05 17:05:10 +07:00
parent 2a1e63be14
commit 6bd5f6af83
7 changed files with 74 additions and 33 deletions

@ -22,6 +22,7 @@ return array(
'OCA\\Files_External\\Command\\Scan' => $baseDir . '/../lib/Command/Scan.php',
'OCA\\Files_External\\Command\\StorageAuthBase' => $baseDir . '/../lib/Command/StorageAuthBase.php',
'OCA\\Files_External\\Command\\Verify' => $baseDir . '/../lib/Command/Verify.php',
'OCA\\Files_External\\ConfigLexicon' => $baseDir . '/../lib/ConfigLexicon.php',
'OCA\\Files_External\\Config\\ConfigAdapter' => $baseDir . '/../lib/Config/ConfigAdapter.php',
'OCA\\Files_External\\Config\\ExternalMountPoint' => $baseDir . '/../lib/Config/ExternalMountPoint.php',
'OCA\\Files_External\\Config\\IConfigHandler' => $baseDir . '/../lib/Config/IConfigHandler.php',

@ -37,6 +37,7 @@ class ComposerStaticInitFiles_External
'OCA\\Files_External\\Command\\Scan' => __DIR__ . '/..' . '/../lib/Command/Scan.php',
'OCA\\Files_External\\Command\\StorageAuthBase' => __DIR__ . '/..' . '/../lib/Command/StorageAuthBase.php',
'OCA\\Files_External\\Command\\Verify' => __DIR__ . '/..' . '/../lib/Command/Verify.php',
'OCA\\Files_External\\ConfigLexicon' => __DIR__ . '/..' . '/../lib/ConfigLexicon.php',
'OCA\\Files_External\\Config\\ConfigAdapter' => __DIR__ . '/..' . '/../lib/Config/ConfigAdapter.php',
'OCA\\Files_External\\Config\\ExternalMountPoint' => __DIR__ . '/..' . '/../lib/Config/ExternalMountPoint.php',
'OCA\\Files_External\\Config\\IConfigHandler' => __DIR__ . '/..' . '/../lib/Config/IConfigHandler.php',

@ -9,6 +9,7 @@ namespace OCA\Files_External\AppInfo;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files_External\Config\ConfigAdapter;
use OCA\Files_External\Config\UserPlaceholderHandler;
use OCA\Files_External\ConfigLexicon;
use OCA\Files_External\Lib\Auth\AmazonS3\AccessKey;
use OCA\Files_External\Lib\Auth\Builtin;
use OCA\Files_External\Lib\Auth\NullMechanism;
@ -73,6 +74,7 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
$context->registerEventListener(GroupDeletedEvent::class, GroupDeletedListener::class);
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
$context->registerConfigLexicon(ConfigLexicon::class);
}
public function boot(IBootContext $context): void {

@ -0,0 +1,41 @@
<?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;
use NCU\Config\Lexicon\ConfigLexiconEntry;
use NCU\Config\Lexicon\ConfigLexiconStrictness;
use NCU\Config\Lexicon\IConfigLexicon;
use NCU\Config\ValueType;
/**
* Config Lexicon for files_sharing.
*
* Please Add & Manage your Config Keys in that file and keep the Lexicon up to date!
*
* {@see IConfigLexicon}
*/
class ConfigLexicon implements IConfigLexicon {
public const ALLOW_USER_MOUNTING = 'allow_user_mounting';
public const USER_MOUNTING_BACKENDS = 'user_mounting_backends';
public function getStrictness(): ConfigLexiconStrictness {
return ConfigLexiconStrictness::NOTICE;
}
public function getAppConfigs(): array {
return [
new ConfigLexiconEntry(self::ALLOW_USER_MOUNTING, ValueType::BOOL, false, 'allow users to mount their own external filesystems', true),
new ConfigLexiconEntry(self::USER_MOUNTING_BACKENDS, ValueType::STRING, '', 'list of mounting backends available for users', true),
];
}
public function getUserConfigs(): array {
return [];
}
}

@ -10,10 +10,11 @@ namespace OCA\Files_External\Listener;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files_External\AppInfo\Application;
use OCA\Files_External\ConfigLexicon;
use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IConfig;
use OCP\IAppConfig;
use OCP\Util;
/**
@ -22,7 +23,7 @@ use OCP\Util;
class LoadAdditionalListener implements IEventListener {
public function __construct(
private IConfig $config,
private readonly IAppConfig $appConfig,
private IInitialState $initialState,
) {
}
@ -32,7 +33,7 @@ class LoadAdditionalListener implements IEventListener {
return;
}
$allowUserMounting = $this->config->getAppValue('files_external', 'allow_user_mounting', 'no') === 'yes';
$allowUserMounting = $this->appConfig->getValueBool('files_external', ConfigLexicon::ALLOW_USER_MOUNTING);
$this->initialState->provideInitialState('allowUserMounting', $allowUserMounting);
Util::addInitScript(Application::APP_ID, 'init');

@ -7,14 +7,14 @@
namespace OCA\Files_External\Service;
use OCA\Files_External\Config\IConfigHandler;
use OCA\Files_External\ConfigLexicon;
use OCA\Files_External\Lib\Auth\AuthMechanism;
use OCA\Files_External\Lib\Backend\Backend;
use OCA\Files_External\Lib\Config\IAuthMechanismProvider;
use OCA\Files_External\Lib\Config\IBackendProvider;
use OCP\EventDispatcher\GenericEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
use OCP\IAppConfig;
use OCP\Server;
/**
@ -56,19 +56,12 @@ class BackendService {
private $configHandlers = [];
/**
* @param IConfig $config
*/
public function __construct(
protected IConfig $config,
protected IAppConfig $appConfig,
) {
// Load config values
if ($this->config->getAppValue('files_external', 'allow_user_mounting', 'yes') !== 'yes') {
$this->userMountingAllowed = false;
}
$this->userMountingBackends = explode(',',
$this->config->getAppValue('files_external', 'user_mounting_backends', '')
);
$this->userMountingAllowed = $appConfig->getValueBool('files_external', ConfigLexicon::ALLOW_USER_MOUNTING);
$this->userMountingBackends = explode(',', $appConfig->getValueString('files_external', ConfigLexicon::USER_MOUNTING_BACKENDS));
// if no backend is in the list an empty string is in the array and user mounting is disabled
if ($this->userMountingBackends === ['']) {

@ -12,15 +12,15 @@ use OCA\Files_External\Lib\Backend\Backend;
use OCA\Files_External\Lib\Config\IAuthMechanismProvider;
use OCA\Files_External\Lib\Config\IBackendProvider;
use OCA\Files_External\Service\BackendService;
use OCP\IConfig;
use OCP\IAppConfig;
class BackendServiceTest extends \Test\TestCase {
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
protected $config;
/** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
protected $appConfig;
protected function setUp(): void {
$this->config = $this->createMock(IConfig::class);
$this->appConfig = $this->createMock(IAppConfig::class);
}
/**
@ -52,7 +52,7 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testRegisterBackend(): void {
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$backend = $this->getBackendMock('\Foo\Bar');
@ -80,7 +80,7 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testBackendProvider(): void {
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$backend1 = $this->getBackendMock('\Foo\Bar');
$backend2 = $this->getBackendMock('\Bar\Foo');
@ -99,7 +99,7 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testAuthMechanismProvider(): void {
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$backend1 = $this->getAuthMechanismMock('\Foo\Bar');
$backend2 = $this->getAuthMechanismMock('\Bar\Foo');
@ -118,7 +118,7 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testMultipleBackendProviders(): void {
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$backend1a = $this->getBackendMock('\Foo\Bar');
$backend1b = $this->getBackendMock('\Bar\Foo');
@ -146,14 +146,16 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testUserMountingBackends(): void {
$this->config->expects($this->exactly(2))
->method('getAppValue')
->willReturnMap([
['files_external', 'allow_user_mounting', 'yes', 'yes'],
['files_external', 'user_mounting_backends', '', 'identifier:\User\Mount\Allowed,identifier_alias']
]);
$this->appConfig->expects($this->once())
->method('getValueString')
->with('files_external', 'user_mounting_backends')
->willReturn('identifier:\User\Mount\Allowed,identifier_alias');
$this->appConfig->expects($this->once())
->method('getValueBool')
->with('files_external', 'allow_user_mounting')
->willReturn(true);
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
$backendAllowed->expects($this->never())
@ -177,7 +179,7 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testGetAvailableBackends(): void {
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$backendAvailable = $this->getBackendMock('\Backend\Available');
$backendAvailable->expects($this->once())
@ -220,7 +222,7 @@ class BackendServiceTest extends \Test\TestCase {
public function testRegisterConfigHandlerInvalid(array $placeholders): void {
$this->expectException(\RuntimeException::class);
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$mock = $this->createMock(IConfigHandler::class);
$cb = function () use ($mock) {
return $mock;
@ -231,7 +233,7 @@ class BackendServiceTest extends \Test\TestCase {
}
public function testConfigHandlers(): void {
$service = new BackendService($this->config);
$service = new BackendService($this->appConfig);
$mock = $this->createMock(IConfigHandler::class);
$mock->expects($this->exactly(3))
->method('handle');