Merge pull request #24585 from owncloud/files_external_lazy
Load external storage backends/auth mechanisms lazily
This commit is contained in:
commit
4728308a9e
|
@ -30,20 +30,26 @@ use \OCP\AppFramework\App;
|
||||||
use OCP\AppFramework\IAppContainer;
|
use OCP\AppFramework\IAppContainer;
|
||||||
use \OCP\IContainer;
|
use \OCP\IContainer;
|
||||||
use \OCA\Files_External\Service\BackendService;
|
use \OCA\Files_External\Service\BackendService;
|
||||||
|
use \OCA\Files_External\Lib\Config\IBackendProvider;
|
||||||
|
use \OCA\Files_External\Lib\Config\IAuthMechanismProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package OCA\Files_External\Appinfo
|
* @package OCA\Files_External\Appinfo
|
||||||
*/
|
*/
|
||||||
class Application extends App {
|
class Application extends App implements IBackendProvider, IAuthMechanismProvider {
|
||||||
|
|
||||||
public function __construct(array $urlParams = array()) {
|
public function __construct(array $urlParams = array()) {
|
||||||
parent::__construct('files_external', $urlParams);
|
parent::__construct('files_external', $urlParams);
|
||||||
|
|
||||||
$this->getContainer()->registerService('OCP\Files\Config\IUserMountCache', function (IAppContainer $c) {
|
$container = $this->getContainer();
|
||||||
|
|
||||||
|
$container->registerService('OCP\Files\Config\IUserMountCache', function (IAppContainer $c) {
|
||||||
return $c->getServer()->query('UserMountCache');
|
return $c->getServer()->query('UserMountCache');
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->loadBackends();
|
$backendService = $container->query('OCA\\Files_External\\Service\\BackendService');
|
||||||
$this->loadAuthMechanisms();
|
$backendService->registerBackendProvider($this);
|
||||||
|
$backendService->registerAuthMechanismProvider($this);
|
||||||
|
|
||||||
// app developers: do NOT depend on this! it will disappear with oC 9.0!
|
// app developers: do NOT depend on this! it will disappear with oC 9.0!
|
||||||
\OC::$server->getEventDispatcher()->dispatch(
|
\OC::$server->getEventDispatcher()->dispatch(
|
||||||
|
@ -63,13 +69,12 @@ class Application extends App {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load storage backends provided by this app
|
* @{inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function loadBackends() {
|
public function getBackends() {
|
||||||
$container = $this->getContainer();
|
$container = $this->getContainer();
|
||||||
$service = $container->query('OCA\\Files_External\\Service\\BackendService');
|
|
||||||
|
|
||||||
$service->registerBackends([
|
$backends = [
|
||||||
$container->query('OCA\Files_External\Lib\Backend\Local'),
|
$container->query('OCA\Files_External\Lib\Backend\Local'),
|
||||||
$container->query('OCA\Files_External\Lib\Backend\FTP'),
|
$container->query('OCA\Files_External\Lib\Backend\FTP'),
|
||||||
$container->query('OCA\Files_External\Lib\Backend\DAV'),
|
$container->query('OCA\Files_External\Lib\Backend\DAV'),
|
||||||
|
@ -80,24 +85,25 @@ class Application extends App {
|
||||||
$container->query('OCA\Files_External\Lib\Backend\Google'),
|
$container->query('OCA\Files_External\Lib\Backend\Google'),
|
||||||
$container->query('OCA\Files_External\Lib\Backend\Swift'),
|
$container->query('OCA\Files_External\Lib\Backend\Swift'),
|
||||||
$container->query('OCA\Files_External\Lib\Backend\SFTP_Key'),
|
$container->query('OCA\Files_External\Lib\Backend\SFTP_Key'),
|
||||||
]);
|
];
|
||||||
|
|
||||||
if (!\OC_Util::runningOnWindows()) {
|
if (!\OC_Util::runningOnWindows()) {
|
||||||
$service->registerBackends([
|
$backends += [
|
||||||
$container->query('OCA\Files_External\Lib\Backend\SMB'),
|
$container->query('OCA\Files_External\Lib\Backend\SMB'),
|
||||||
$container->query('OCA\Files_External\Lib\Backend\SMB_OC'),
|
$container->query('OCA\Files_External\Lib\Backend\SMB_OC'),
|
||||||
]);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $backends;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load authentication mechanisms provided by this app
|
* @{inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function loadAuthMechanisms() {
|
public function getAuthMechanisms() {
|
||||||
$container = $this->getContainer();
|
$container = $this->getContainer();
|
||||||
$service = $container->query('OCA\\Files_External\\Service\\BackendService');
|
|
||||||
|
|
||||||
$service->registerAuthMechanisms([
|
return [
|
||||||
// AuthMechanism::SCHEME_NULL mechanism
|
// AuthMechanism::SCHEME_NULL mechanism
|
||||||
$container->query('OCA\Files_External\Lib\Auth\NullMechanism'),
|
$container->query('OCA\Files_External\Lib\Auth\NullMechanism'),
|
||||||
|
|
||||||
|
@ -123,7 +129,7 @@ class Application extends App {
|
||||||
|
|
||||||
// Specialized mechanisms
|
// Specialized mechanisms
|
||||||
$container->query('OCA\Files_External\Lib\Auth\AmazonS3\AccessKey'),
|
$container->query('OCA\Files_External\Lib\Auth\AmazonS3\AccessKey'),
|
||||||
]);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Files_External\Lib\Config;
|
||||||
|
|
||||||
|
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider of external storage auth mechanisms
|
||||||
|
* @since 9.1.0
|
||||||
|
*/
|
||||||
|
interface IAuthMechanismProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 9.1.0
|
||||||
|
* @return AuthMechanism[]
|
||||||
|
*/
|
||||||
|
public function getAuthMechanisms();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Files_External\Lib\Config;
|
||||||
|
|
||||||
|
use \OCA\Files_External\Lib\Backend\Backend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider of external storage backends
|
||||||
|
* @since 9.1.0
|
||||||
|
*/
|
||||||
|
interface IBackendProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 9.1.0
|
||||||
|
* @return Backend[]
|
||||||
|
*/
|
||||||
|
public function getBackends();
|
||||||
|
|
||||||
|
}
|
|
@ -26,6 +26,8 @@ use \OCP\IConfig;
|
||||||
|
|
||||||
use \OCA\Files_External\Lib\Backend\Backend;
|
use \OCA\Files_External\Lib\Backend\Backend;
|
||||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||||
|
use \OCA\Files_External\Lib\Config\IBackendProvider;
|
||||||
|
use \OCA\Files_External\Lib\Config\IAuthMechanismProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service class to manage backend definitions
|
* Service class to manage backend definitions
|
||||||
|
@ -55,9 +57,15 @@ class BackendService {
|
||||||
/** @var Backend[] */
|
/** @var Backend[] */
|
||||||
private $backends = [];
|
private $backends = [];
|
||||||
|
|
||||||
|
/** @var IBackendProvider[] */
|
||||||
|
private $backendProviders = [];
|
||||||
|
|
||||||
/** @var AuthMechanism[] */
|
/** @var AuthMechanism[] */
|
||||||
private $authMechanisms = [];
|
private $authMechanisms = [];
|
||||||
|
|
||||||
|
/** @var IAuthMechanismProvider[] */
|
||||||
|
private $authMechanismProviders = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IConfig $config
|
* @param IConfig $config
|
||||||
*/
|
*/
|
||||||
|
@ -80,9 +88,44 @@ class BackendService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a backend provider
|
||||||
|
*
|
||||||
|
* @since 9.1.0
|
||||||
|
* @param IBackendProvider $provider
|
||||||
|
*/
|
||||||
|
public function registerBackendProvider(IBackendProvider $provider) {
|
||||||
|
$this->backendProviders[] = $provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadBackendProviders() {
|
||||||
|
foreach ($this->backendProviders as $provider) {
|
||||||
|
$this->registerBackends($provider->getBackends());
|
||||||
|
}
|
||||||
|
$this->backendProviders = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an auth mechanism provider
|
||||||
|
*
|
||||||
|
* @since 9.1.0
|
||||||
|
* @param IAuthMechanismProvider $provider
|
||||||
|
*/
|
||||||
|
public function registerAuthMechanismProvider(IAuthMechanismProvider $provider) {
|
||||||
|
$this->authMechanismProviders[] = $provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadAuthMechanismProviders() {
|
||||||
|
foreach ($this->authMechanismProviders as $provider) {
|
||||||
|
$this->registerAuthMechanisms($provider->getAuthMechanisms());
|
||||||
|
}
|
||||||
|
$this->authMechanismProviders = [];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a backend
|
* Register a backend
|
||||||
*
|
*
|
||||||
|
* @deprecated 9.1.0 use registerBackendProvider()
|
||||||
* @param Backend $backend
|
* @param Backend $backend
|
||||||
*/
|
*/
|
||||||
public function registerBackend(Backend $backend) {
|
public function registerBackend(Backend $backend) {
|
||||||
|
@ -95,6 +138,7 @@ class BackendService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated 9.1.0 use registerBackendProvider()
|
||||||
* @param Backend[] $backends
|
* @param Backend[] $backends
|
||||||
*/
|
*/
|
||||||
public function registerBackends(array $backends) {
|
public function registerBackends(array $backends) {
|
||||||
|
@ -105,6 +149,7 @@ class BackendService {
|
||||||
/**
|
/**
|
||||||
* Register an authentication mechanism
|
* Register an authentication mechanism
|
||||||
*
|
*
|
||||||
|
* @deprecated 9.1.0 use registerAuthMechanismProvider()
|
||||||
* @param AuthMechanism $authMech
|
* @param AuthMechanism $authMech
|
||||||
*/
|
*/
|
||||||
public function registerAuthMechanism(AuthMechanism $authMech) {
|
public function registerAuthMechanism(AuthMechanism $authMech) {
|
||||||
|
@ -117,6 +162,7 @@ class BackendService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated 9.1.0 use registerAuthMechanismProvider()
|
||||||
* @param AuthMechanism[] $mechanisms
|
* @param AuthMechanism[] $mechanisms
|
||||||
*/
|
*/
|
||||||
public function registerAuthMechanisms(array $mechanisms) {
|
public function registerAuthMechanisms(array $mechanisms) {
|
||||||
|
@ -131,6 +177,7 @@ class BackendService {
|
||||||
* @return Backend[]
|
* @return Backend[]
|
||||||
*/
|
*/
|
||||||
public function getBackends() {
|
public function getBackends() {
|
||||||
|
$this->loadBackendProviders();
|
||||||
// only return real identifiers, no aliases
|
// only return real identifiers, no aliases
|
||||||
$backends = [];
|
$backends = [];
|
||||||
foreach ($this->backends as $backend) {
|
foreach ($this->backends as $backend) {
|
||||||
|
@ -155,6 +202,7 @@ class BackendService {
|
||||||
* @return Backend|null
|
* @return Backend|null
|
||||||
*/
|
*/
|
||||||
public function getBackend($identifier) {
|
public function getBackend($identifier) {
|
||||||
|
$this->loadBackendProviders();
|
||||||
if (isset($this->backends[$identifier])) {
|
if (isset($this->backends[$identifier])) {
|
||||||
return $this->backends[$identifier];
|
return $this->backends[$identifier];
|
||||||
}
|
}
|
||||||
|
@ -167,6 +215,7 @@ class BackendService {
|
||||||
* @return AuthMechanism[]
|
* @return AuthMechanism[]
|
||||||
*/
|
*/
|
||||||
public function getAuthMechanisms() {
|
public function getAuthMechanisms() {
|
||||||
|
$this->loadAuthMechanismProviders();
|
||||||
// only return real identifiers, no aliases
|
// only return real identifiers, no aliases
|
||||||
$mechanisms = [];
|
$mechanisms = [];
|
||||||
foreach ($this->authMechanisms as $mechanism) {
|
foreach ($this->authMechanisms as $mechanism) {
|
||||||
|
@ -192,6 +241,7 @@ class BackendService {
|
||||||
* @return AuthMechanism|null
|
* @return AuthMechanism|null
|
||||||
*/
|
*/
|
||||||
public function getAuthMechanism($identifier) {
|
public function getAuthMechanism($identifier) {
|
||||||
|
$this->loadAuthMechanismProviders();
|
||||||
if (isset($this->authMechanisms[$identifier])) {
|
if (isset($this->authMechanisms[$identifier])) {
|
||||||
return $this->authMechanisms[$identifier];
|
return $this->authMechanisms[$identifier];
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,20 @@ class BackendServiceTest extends \Test\TestCase {
|
||||||
return $backend;
|
return $backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
*
|
||||||
|
* @return \OCA\Files_External\Lib\Auth\AuthMechanism
|
||||||
|
*/
|
||||||
|
protected function getAuthMechanismMock($class) {
|
||||||
|
$backend = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\AuthMechanism')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$backend->method('getIdentifier')->will($this->returnValue('identifier:'.$class));
|
||||||
|
$backend->method('getIdentifierAliases')->will($this->returnValue(['identifier:'.$class]));
|
||||||
|
return $backend;
|
||||||
|
}
|
||||||
|
|
||||||
public function testRegisterBackend() {
|
public function testRegisterBackend() {
|
||||||
$service = new BackendService($this->config, $this->l10n);
|
$service = new BackendService($this->config, $this->l10n);
|
||||||
|
|
||||||
|
@ -76,6 +90,68 @@ class BackendServiceTest extends \Test\TestCase {
|
||||||
$this->assertArrayNotHasKey('identifier_alias', $backends);
|
$this->assertArrayNotHasKey('identifier_alias', $backends);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBackendProvider() {
|
||||||
|
$service = new BackendService($this->config, $this->l10n);
|
||||||
|
|
||||||
|
$backend1 = $this->getBackendMock('\Foo\Bar');
|
||||||
|
$backend2 = $this->getBackendMock('\Bar\Foo');
|
||||||
|
|
||||||
|
$providerMock = $this->getMock('\OCA\Files_External\Lib\Config\IBackendProvider');
|
||||||
|
$providerMock->expects($this->once())
|
||||||
|
->method('getBackends')
|
||||||
|
->willReturn([$backend1, $backend2]);
|
||||||
|
$service->registerBackendProvider($providerMock);
|
||||||
|
|
||||||
|
$this->assertEquals($backend1, $service->getBackend('identifier:\Foo\Bar'));
|
||||||
|
$this->assertEquals($backend2, $service->getBackend('identifier:\Bar\Foo'));
|
||||||
|
|
||||||
|
$this->assertCount(2, $service->getBackends());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthMechanismProvider() {
|
||||||
|
$service = new BackendService($this->config, $this->l10n);
|
||||||
|
|
||||||
|
$backend1 = $this->getAuthMechanismMock('\Foo\Bar');
|
||||||
|
$backend2 = $this->getAuthMechanismMock('\Bar\Foo');
|
||||||
|
|
||||||
|
$providerMock = $this->getMock('\OCA\Files_External\Lib\Config\IAuthMechanismProvider');
|
||||||
|
$providerMock->expects($this->once())
|
||||||
|
->method('getAuthMechanisms')
|
||||||
|
->willReturn([$backend1, $backend2]);
|
||||||
|
$service->registerAuthMechanismProvider($providerMock);
|
||||||
|
|
||||||
|
$this->assertEquals($backend1, $service->getAuthMechanism('identifier:\Foo\Bar'));
|
||||||
|
$this->assertEquals($backend2, $service->getAuthMechanism('identifier:\Bar\Foo'));
|
||||||
|
|
||||||
|
$this->assertCount(2, $service->getAuthMechanisms());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMultipleBackendProviders() {
|
||||||
|
$service = new BackendService($this->config, $this->l10n);
|
||||||
|
|
||||||
|
$backend1a = $this->getBackendMock('\Foo\Bar');
|
||||||
|
$backend1b = $this->getBackendMock('\Bar\Foo');
|
||||||
|
|
||||||
|
$backend2 = $this->getBackendMock('\Dead\Beef');
|
||||||
|
|
||||||
|
$provider1Mock = $this->getMock('\OCA\Files_External\Lib\Config\IBackendProvider');
|
||||||
|
$provider1Mock->expects($this->once())
|
||||||
|
->method('getBackends')
|
||||||
|
->willReturn([$backend1a, $backend1b]);
|
||||||
|
$service->registerBackendProvider($provider1Mock);
|
||||||
|
$provider2Mock = $this->getMock('\OCA\Files_External\Lib\Config\IBackendProvider');
|
||||||
|
$provider2Mock->expects($this->once())
|
||||||
|
->method('getBackends')
|
||||||
|
->willReturn([$backend2]);
|
||||||
|
$service->registerBackendProvider($provider2Mock);
|
||||||
|
|
||||||
|
$this->assertEquals($backend1a, $service->getBackend('identifier:\Foo\Bar'));
|
||||||
|
$this->assertEquals($backend1b, $service->getBackend('identifier:\Bar\Foo'));
|
||||||
|
$this->assertEquals($backend2, $service->getBackend('identifier:\Dead\Beef'));
|
||||||
|
|
||||||
|
$this->assertCount(3, $service->getBackends());
|
||||||
|
}
|
||||||
|
|
||||||
public function testUserMountingBackends() {
|
public function testUserMountingBackends() {
|
||||||
$this->config->expects($this->exactly(2))
|
$this->config->expects($this->exactly(2))
|
||||||
->method('getAppValue')
|
->method('getAppValue')
|
||||||
|
|
Loading…
Reference in New Issue