aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_external
diff options
context:
space:
mode:
authorRobin McCorkell <rmccorkell@owncloud.com>2015-08-11 18:45:07 +0100
committerRobin McCorkell <rmccorkell@owncloud.com>2015-08-19 10:05:11 +0100
commit37beb58c6f395523d8e2934870c5f52a8c6f6df0 (patch)
treeb14325a790ddaf7236c3f8c1939ce9ef10df58bb /apps/files_external
parent74237a9c44192fb98944ea7f3c14fa6f22c0814b (diff)
downloadnextcloud-server-37beb58c6f395523d8e2934870c5f52a8c6f6df0.tar.gz
nextcloud-server-37beb58c6f395523d8e2934870c5f52a8c6f6df0.zip
Introduce BackendService for managing external storage backends
Backends are registered to the BackendService through new data structures: Backends are concrete classes, deriving from \OCA\Files_External\Lib\Backend\Backend. During construction, the various configuration parameters of the Backend can be set, in a design similar to Symfony Console. DefinitionParameter stores a parameter configuration for an external storage: name of parameter, human-readable name, type of parameter (text, password, hidden, checkbox), flags (optional or not). Storages in the StoragesController now get their parameters validated server-side (fixes a TODO).
Diffstat (limited to 'apps/files_external')
-rw-r--r--apps/files_external/appinfo/app.php13
-rw-r--r--apps/files_external/appinfo/application.php15
-rw-r--r--apps/files_external/controller/globalstoragescontroller.php41
-rw-r--r--apps/files_external/controller/storagescontroller.php69
-rw-r--r--apps/files_external/controller/userstoragescontroller.php42
-rw-r--r--apps/files_external/lib/backend/backend.php94
-rw-r--r--apps/files_external/lib/config.php255
-rw-r--r--apps/files_external/lib/config/configadapter.php14
-rw-r--r--apps/files_external/lib/definitionparameter.php179
-rw-r--r--apps/files_external/lib/dependencytrait.php86
-rw-r--r--apps/files_external/lib/frontenddefinitiontrait.php147
-rw-r--r--apps/files_external/lib/missingdependency.php64
-rw-r--r--apps/files_external/lib/personalmount.php45
-rw-r--r--apps/files_external/lib/prioritytrait.php60
-rw-r--r--apps/files_external/lib/storageconfig.php45
-rw-r--r--apps/files_external/lib/storagemodifiertrait.php51
-rw-r--r--apps/files_external/lib/visibilitytrait.php129
-rw-r--r--apps/files_external/personal.php34
-rw-r--r--apps/files_external/service/backendservice.php170
-rw-r--r--apps/files_external/service/storagesservice.php68
-rw-r--r--apps/files_external/service/userstoragesservice.php4
-rw-r--r--apps/files_external/settings.php51
-rw-r--r--apps/files_external/templates/settings.php215
-rw-r--r--apps/files_external/tests/controller/globalstoragescontrollertest.php4
-rw-r--r--apps/files_external/tests/controller/storagescontrollertest.php61
-rw-r--r--apps/files_external/tests/controller/userstoragescontrollertest.php51
-rw-r--r--apps/files_external/tests/dynamicmountconfig.php104
-rw-r--r--apps/files_external/tests/service/globalstoragesservicetest.php26
-rw-r--r--apps/files_external/tests/service/storagesservicetest.php47
-rw-r--r--apps/files_external/tests/service/userstoragesservicetest.php4
-rw-r--r--apps/files_external/tests/storageconfigtest.php8
31 files changed, 1638 insertions, 558 deletions
diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php
index 66897eba3d3..37a489535ea 100644
--- a/apps/files_external/appinfo/app.php
+++ b/apps/files_external/appinfo/app.php
@@ -30,9 +30,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
-$app = new \OCA\Files_external\Appinfo\Application();
-
-$l = \OC::$server->getL10N('files_external');
OC::$CLASSPATH['OC\Files\Storage\StreamWrapper'] = 'files_external/lib/streamwrapper.php';
OC::$CLASSPATH['OC\Files\Storage\FTP'] = 'files_external/lib/ftp.php';
@@ -50,6 +47,11 @@ OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php';
require_once __DIR__ . '/../3rdparty/autoload.php';
+$app = new \OCA\Files_external\Appinfo\Application();
+$appContainer = $app->getContainer();
+
+$l = \OC::$server->getL10N('files_external');
+
OCP\App::registerAdmin('files_external', 'settings');
if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == 'yes') {
OCP\App::registerPersonal('files_external', 'personal');
@@ -63,6 +65,9 @@ if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == '
"name" => $l->t('External storage')
]);
+// Teach OC_Mount_Config about the AppFramework
+\OC_Mount_Config::initApp($appContainer);
+
// connecting hooks
OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\OC_Mount_Config', 'initMountPointsHook');
OCP\Util::connectHook('OC_User', 'post_login', 'OC\Files\Storage\SMB_OC', 'login');
@@ -237,5 +242,5 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\SFTP_Key', [
'custom' => 'sftp_key',
]
);
-$mountProvider = new \OCA\Files_External\Config\ConfigAdapter();
+$mountProvider = $appContainer->query('OCA\Files_External\Config\ConfigAdapter');
\OC::$server->getMountProviderCollection()->registerProvider($mountProvider);
diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php
index d77a302466c..b8b1fdaa27e 100644
--- a/apps/files_external/appinfo/application.php
+++ b/apps/files_external/appinfo/application.php
@@ -3,6 +3,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Ross Nicoll <jrn@jrn.me.uk>
* @author Vincent Petry <pvince81@owncloud.com>
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
@@ -26,6 +27,9 @@ namespace OCA\Files_External\AppInfo;
use \OCA\Files_External\Controller\AjaxController;
use \OCP\AppFramework\App;
use \OCP\IContainer;
+use \OCA\Files_External\Service\BackendService;
+use \OCA\Files_External\Lib\BackendConfig;
+use \OCA\Files_External\Lib\BackendParameter;
/**
* @package OCA\Files_External\Appinfo
@@ -45,5 +49,16 @@ class Application extends App {
$c->query('Request')
);
});
+
+ $this->loadBackends();
}
+
+ /**
+ * Load storage backends provided by this app
+ */
+ protected function loadBackends() {
+ $container = $this->getContainer();
+ $service = $container->query('OCA\\Files_External\\Service\\BackendService');
+ }
+
}
diff --git a/apps/files_external/controller/globalstoragescontroller.php b/apps/files_external/controller/globalstoragescontroller.php
index 33f870d48e3..11f7fd6afa5 100644
--- a/apps/files_external/controller/globalstoragescontroller.php
+++ b/apps/files_external/controller/globalstoragescontroller.php
@@ -81,14 +81,18 @@ class GlobalStoragesController extends StoragesController {
$applicableGroups,
$priority
) {
- $newStorage = new StorageConfig();
- $newStorage->setMountPoint($mountPoint);
- $newStorage->setBackendClass($backendClass);
- $newStorage->setBackendOptions($backendOptions);
- $newStorage->setMountOptions($mountOptions);
- $newStorage->setApplicableUsers($applicableUsers);
- $newStorage->setApplicableGroups($applicableGroups);
- $newStorage->setPriority($priority);
+ $newStorage = $this->createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions,
+ $applicableUsers,
+ $applicableGroups,
+ $priority
+ );
+ if ($newStorage instanceof DataResponse) {
+ return $newStorage;
+ }
$response = $this->validate($newStorage);
if (!empty($response)) {
@@ -129,14 +133,19 @@ class GlobalStoragesController extends StoragesController {
$applicableGroups,
$priority
) {
- $storage = new StorageConfig($id);
- $storage->setMountPoint($mountPoint);
- $storage->setBackendClass($backendClass);
- $storage->setBackendOptions($backendOptions);
- $storage->setMountOptions($mountOptions);
- $storage->setApplicableUsers($applicableUsers);
- $storage->setApplicableGroups($applicableGroups);
- $storage->setPriority($priority);
+ $storage = $this->createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions,
+ $applicableUsers,
+ $applicableGroups,
+ $priority
+ );
+ if ($storage instanceof DataResponse) {
+ return $storage;
+ }
+ $storage->setId($id);
$response = $this->validate($storage);
if (!empty($response)) {
diff --git a/apps/files_external/controller/storagescontroller.php b/apps/files_external/controller/storagescontroller.php
index c09ceacc7d7..c653b51bf89 100644
--- a/apps/files_external/controller/storagescontroller.php
+++ b/apps/files_external/controller/storagescontroller.php
@@ -32,6 +32,7 @@ use \OCP\AppFramework\Http;
use \OCA\Files_external\Service\StoragesService;
use \OCA\Files_external\NotFoundException;
use \OCA\Files_external\Lib\StorageConfig;
+use \OCA\Files_External\Lib\Backend\Backend;
/**
* Base class for storages controllers
@@ -72,6 +73,48 @@ abstract class StoragesController extends Controller {
}
/**
+ * Create a storage from its parameters
+ *
+ * @param string $mountPoint storage mount point
+ * @param string $backendClass backend class name
+ * @param array $backendOptions backend-specific options
+ * @param array|null $mountOptions mount-specific options
+ * @param array|null $applicableUsers users for which to mount the storage
+ * @param array|null $applicableGroups groups for which to mount the storage
+ * @param int|null $priority priority
+ *
+ * @return StorageConfig|DataResponse
+ */
+ protected function createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions = null,
+ $applicableUsers = null,
+ $applicableGroups = null,
+ $priority = null
+ ) {
+ try {
+ return $this->service->createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions,
+ $applicableUsers,
+ $applicableGroups,
+ $priority
+ );
+ } catch (\InvalidArgumentException $e) {
+ return new DataResponse(
+ [
+ 'message' => (string)$this->l10n->t('Invalid backend class "%s"', [$backendClass])
+ ],
+ Http::STATUS_UNPROCESSABLE_ENTITY
+ );
+ }
+ }
+
+ /**
* Validate storage config
*
* @param StorageConfig $storage storage config
@@ -89,14 +132,24 @@ abstract class StoragesController extends Controller {
);
}
- // TODO: validate that other attrs are set
-
- $backends = \OC_Mount_Config::getBackends();
- if (!isset($backends[$storage->getBackendClass()])) {
+ /** @var Backend */
+ $backend = $storage->getBackend();
+ if (!$backend || $backend->checkDependencies()) {
// invalid backend
return new DataResponse(
array(
- 'message' => (string)$this->l10n->t('Invalid storage backend "%s"', array($storage->getBackendClass()))
+ 'message' => (string)$this->l10n->t('Invalid storage backend "%s"', [
+ $storage->getBackend()->getClass()
+ ])
+ ),
+ Http::STATUS_UNPROCESSABLE_ENTITY
+ );
+ }
+ if (!$backend->validateStorage($storage)) {
+ // unsatisfied parameters
+ return new DataResponse(
+ array(
+ 'message' => (string)$this->l10n->t('Unsatisfied backend parameters')
),
Http::STATUS_UNPROCESSABLE_ENTITY
);
@@ -114,10 +167,14 @@ abstract class StoragesController extends Controller {
* @param StorageConfig $storage storage configuration
*/
protected function updateStorageStatus(StorageConfig &$storage) {
+ /** @var Backend */
+ $backend = $storage->getBackend();
+ $backend->manipulateStorageConfig($storage);
+
// update status (can be time-consuming)
$storage->setStatus(
\OC_Mount_Config::getBackendStatus(
- $storage->getBackendClass(),
+ $storage->getBackend()->getStorageClass(),
$storage->getBackendOptions(),
false
)
diff --git a/apps/files_external/controller/userstoragescontroller.php b/apps/files_external/controller/userstoragescontroller.php
index f5d22e5caa6..5a5bff7ba70 100644
--- a/apps/files_external/controller/userstoragescontroller.php
+++ b/apps/files_external/controller/userstoragescontroller.php
@@ -30,8 +30,10 @@ use \OCP\AppFramework\Http\DataResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http;
use \OCA\Files_external\Service\UserStoragesService;
+use \OCA\Files_External\Service\BackendService;
use \OCA\Files_external\NotFoundException;
use \OCA\Files_external\Lib\StorageConfig;
+use \OCA\Files_External\Lib\Backend\Backend;
/**
* User storages controller
@@ -69,17 +71,20 @@ class UserStoragesController extends StoragesController {
protected function validate(StorageConfig $storage) {
$result = parent::validate($storage);
- if ($result != null) {
+ if ($result !== null) {
return $result;
}
// Verify that the mount point applies for the current user
// Prevent non-admin users from mounting local storage and other disabled backends
- $allowedBackends = \OC_Mount_Config::getPersonalBackends();
- if (!isset($allowedBackends[$storage->getBackendClass()])) {
+ /** @var Backend */
+ $backend = $storage->getBackend();
+ if (!$backend->isVisibleFor(BackendService::VISIBILITY_PERSONAL)) {
return new DataResponse(
array(
- 'message' => (string)$this->l10n->t('Invalid storage backend "%s"', array($storage->getBackendClass()))
+ 'message' => (string)$this->l10n->t('Admin-only storage backend "%s"', [
+ $storage->getBackend()->getClass()
+ ])
),
Http::STATUS_UNPROCESSABLE_ENTITY
);
@@ -117,11 +122,15 @@ class UserStoragesController extends StoragesController {
$backendOptions,
$mountOptions
) {
- $newStorage = new StorageConfig();
- $newStorage->setMountPoint($mountPoint);
- $newStorage->setBackendClass($backendClass);
- $newStorage->setBackendOptions($backendOptions);
- $newStorage->setMountOptions($mountOptions);
+ $newStorage = $this->createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions
+ );
+ if ($newStorage instanceOf DataResponse) {
+ return $newStorage;
+ }
$response = $this->validate($newStorage);
if (!empty($response)) {
@@ -157,11 +166,16 @@ class UserStoragesController extends StoragesController {
$backendOptions,
$mountOptions
) {
- $storage = new StorageConfig($id);
- $storage->setMountPoint($mountPoint);
- $storage->setBackendClass($backendClass);
- $storage->setBackendOptions($backendOptions);
- $storage->setMountOptions($mountOptions);
+ $storage = $this->createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions
+ );
+ if ($storage instanceOf DataResponse) {
+ return $storage;
+ }
+ $storage->setId($id);
$response = $this->validate($storage);
if (!empty($response)) {
diff --git a/apps/files_external/lib/backend/backend.php b/apps/files_external/lib/backend/backend.php
new file mode 100644
index 00000000000..e7cd27a1d6c
--- /dev/null
+++ b/apps/files_external/lib/backend/backend.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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\Backend;
+
+use \OCA\Files_External\Lib\StorageConfig;
+use \OCA\Files_External\Lib\VisibilityTrait;
+use \OCA\Files_External\Lib\FrontendDefinitionTrait;
+use \OCA\Files_External\Lib\PriorityTrait;
+use \OCA\Files_External\Lib\DependencyTrait;
+use \OCA\Files_External\Lib\StorageModifierTrait;
+
+/**
+ * Storage backend
+ */
+class Backend implements \JsonSerializable {
+
+ use VisibilityTrait;
+ use FrontendDefinitionTrait;
+ use PriorityTrait;
+ use DependencyTrait;
+ use StorageModifierTrait;
+
+ /** @var string storage class */
+ private $storageClass;
+
+ /**
+ * @return string
+ */
+ public function getClass() {
+ // return storage class for legacy compat
+ return $this->getStorageClass();
+ }
+
+ /**
+ * @return string
+ */
+ public function getStorageClass() {
+ return $this->storageClass;
+ }
+
+ /**
+ * @param string $class
+ * @return self
+ */
+ public function setStorageClass($class) {
+ $this->storageClass = $class;
+ return $this;
+ }
+
+ /**
+ * Serialize into JSON for client-side JS
+ *
+ * @return array
+ */
+ public function jsonSerialize() {
+ $data = $this->jsonSerializeDefinition();
+
+ $data['backend'] = $data['name']; // legacy compat
+ $data['priority'] = $this->getPriority();
+
+ return $data;
+ }
+
+ /**
+ * Check if parameters are satisfied in a StorageConfig
+ *
+ * @param StorageConfig $storage
+ * @return bool
+ */
+ public function validateStorage(StorageConfig $storage) {
+ return $this->validateStorageDefinition($storage);
+ }
+
+}
+
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index 8fcf39cc767..11dec94621a 100644
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -32,6 +32,9 @@
*/
use phpseclib\Crypt\AES;
+use \OCP\AppFramework\IAppContainer;
+use \OCA\Files_External\Lib\BackendConfig;
+use \OCA\Files_External\Service\BackendService;
/**
* Class to configure mount.json globally and for users
@@ -51,71 +54,19 @@ class OC_Mount_Config {
// whether to skip backend test (for unit tests, as this static class is not mockable)
public static $skipTest = false;
- private static $backends = array();
+ /** @var IAppContainer */
+ private static $appContainer;
/**
- * @param string $class
- * @param array $definition
- * @return bool
- */
- public static function registerBackend($class, $definition) {
- if (!isset($definition['backend'])) {
- return false;
- }
-
- OC_Mount_Config::$backends[$class] = $definition;
- return true;
- }
-
- /**
- * Setup backends
+ * Teach OC_Mount_Config about the AppFramework
*
- * @return array of previously registered backends
+ * @param IAppContainer $appContainer
*/
- public static function setUp($backends = array()) {
- $backup = self::$backends;
- self::$backends = $backends;
-
- return $backup;
- }
-
- /**
- * Get details on each of the external storage backends, used for the mount config UI
- * If a custom UI is needed, add the key 'custom' and a javascript file with that name will be loaded
- * If the configuration parameter should be secret, add a '*' to the beginning of the value
- * If the configuration parameter is a boolean, add a '!' to the beginning of the value
- * If the configuration parameter is optional, add a '&' to the beginning of the value
- * If the configuration parameter is hidden, add a '#' to the beginning of the value
- *
- * @return array
- */
- public static function getBackends() {
- $sortFunc = function ($a, $b) {
- return strcasecmp($a['backend'], $b['backend']);
- };
-
- $backEnds = array();
-
- foreach (OC_Mount_Config::$backends as $class => $backend) {
- if (isset($backend['has_dependencies']) and $backend['has_dependencies'] === true) {
- if (!method_exists($class, 'checkDependencies')) {
- \OCP\Util::writeLog('files_external',
- "Backend class $class has dependencies but doesn't provide method checkDependencies()",
- \OCP\Util::DEBUG);
- continue;
- } elseif ($class::checkDependencies() !== true) {
- continue;
- }
- }
- $backEnds[$class] = $backend;
- }
-
- uasort($backEnds, $sortFunc);
-
- return $backEnds;
+ public static function initApp(IAppContainer $appContainer) {
+ self::$appContainer = $appContainer;
}
- /**
+ /*
* Hook that mounts the given user's visible mount points
*
* @param array $data
@@ -151,14 +102,14 @@ class OC_Mount_Config {
/**
* Returns the mount points for the given user.
* The mount point is relative to the data directory.
+ * TODO: Move me into StoragesService
*
* @param string $user user
* @return array of mount point string as key, mountpoint config as value
*/
public static function getAbsoluteMountPoints($user) {
$mountPoints = array();
-
- $backends = self::getBackends();
+ $backendService = self::$appContainer->query('OCA\Files_External\Service\BackendService');
// Load system mount points
$mountConfig = self::readData();
@@ -166,18 +117,20 @@ class OC_Mount_Config {
// Global mount points (is this redundant?)
if (isset($mountConfig[self::MOUNT_TYPE_GLOBAL])) {
foreach ($mountConfig[self::MOUNT_TYPE_GLOBAL] as $mountPoint => $options) {
+ $backend = $backendService->getBackend($options['class']);
$options['personal'] = false;
$options['options'] = self::decryptPasswords($options['options']);
if (!isset($options['priority'])) {
- $options['priority'] = $backends[$options['class']]['priority'];
+ $options['priority'] = $backend->getPriority();
}
+
// Override if priority greater
if ((!isset($mountPoints[$mountPoint]))
|| ($options['priority'] >= $mountPoints[$mountPoint]['priority'])
) {
$options['priority_type'] = self::MOUNT_TYPE_GLOBAL;
- $options['backend'] = $backends[$options['class']]['backend'];
+ $options['backend'] = $backend->getText();
$mountPoints[$mountPoint] = $options;
}
}
@@ -190,10 +143,11 @@ class OC_Mount_Config {
foreach ($options as &$option) {
$option = self::setUserVars($user, $option);
}
+ $backend = $backendService->getBackend($options['class']);
$options['personal'] = false;
$options['options'] = self::decryptPasswords($options['options']);
if (!isset($options['priority'])) {
- $options['priority'] = $backends[$options['class']]['priority'];
+ $options['priority'] = $backend->getPriority();
}
// Override if priority greater
@@ -201,7 +155,7 @@ class OC_Mount_Config {
|| ($options['priority'] >= $mountPoints[$mountPoint]['priority'])
) {
$options['priority_type'] = self::MOUNT_TYPE_GLOBAL;
- $options['backend'] = $backends[$options['class']]['backend'];
+ $options['backend'] = $backend->getText();
$mountPoints[$mountPoint] = $options;
}
}
@@ -215,10 +169,11 @@ class OC_Mount_Config {
foreach ($options as &$option) {
$option = self::setUserVars($user, $option);
}
+ $backend = $backendService->getBackend($options['class']);
$options['personal'] = false;
$options['options'] = self::decryptPasswords($options['options']);
if (!isset($options['priority'])) {
- $options['priority'] = $backends[$options['class']]['priority'];
+ $options['priority'] = $backend->getPriority();
}
// Override if priority greater or if priority type different
@@ -227,7 +182,7 @@ class OC_Mount_Config {
|| ($mountPoints[$mountPoint]['priority_type'] !== self::MOUNT_TYPE_GROUP)
) {
$options['priority_type'] = self::MOUNT_TYPE_GROUP;
- $options['backend'] = $backends[$options['class']]['backend'];
+ $options['backend'] = $backend->getText();
$mountPoints[$mountPoint] = $options;
}
}
@@ -243,10 +198,11 @@ class OC_Mount_Config {
foreach ($options as &$option) {
$option = self::setUserVars($user, $option);
}
+ $backend = $backendService->getBackend($options['class']);
$options['personal'] = false;
$options['options'] = self::decryptPasswords($options['options']);
if (!isset($options['priority'])) {
- $options['priority'] = $backends[$options['class']]['priority'];
+ $options['priority'] = $backend->getPriority();
}
// Override if priority greater or if priority type different
@@ -255,7 +211,7 @@ class OC_Mount_Config {
|| ($mountPoints[$mountPoint]['priority_type'] !== self::MOUNT_TYPE_USER)
) {
$options['priority_type'] = self::MOUNT_TYPE_USER;
- $options['backend'] = $backends[$options['class']]['backend'];
+ $options['backend'] = $backend->getText();
$mountPoints[$mountPoint] = $options;
}
}
@@ -263,19 +219,18 @@ class OC_Mount_Config {
}
}
- $personalBackends = self::getPersonalBackends();
-
// Load personal mount points
$mountConfig = self::readData($user);
if (isset($mountConfig[self::MOUNT_TYPE_USER][$user])) {
foreach ($mountConfig[self::MOUNT_TYPE_USER][$user] as $mountPoint => $options) {
- if (isset($personalBackends[$options['class']])) {
+ $backend = $backendService->getBackend($options['class']);
+ if ($backend->isVisibleFor(BackendService::VISIBILITY_PERSONAL)) {
$options['personal'] = true;
$options['options'] = self::decryptPasswords($options['options']);
// Always override previous config
$options['priority_type'] = self::MOUNT_TYPE_PERSONAL;
- $options['backend'] = $backends[$options['class']]['backend'];
+ $options['backend'] = $backend->getText();
$mountPoints[$mountPoint] = $options;
}
}
@@ -304,43 +259,6 @@ class OC_Mount_Config {
return $input;
}
-
- /**
- * Get details on each of the external storage backends, used for the mount config UI
- * Some backends are not available as a personal backend, f.e. Local and such that have
- * been disabled by the admin.
- *
- * If a custom UI is needed, add the key 'custom' and a javascript file with that name will be loaded
- * If the configuration parameter should be secret, add a '*' to the beginning of the value
- * If the configuration parameter is a boolean, add a '!' to the beginning of the value
- * If the configuration parameter is optional, add a '&' to the beginning of the value
- * If the configuration parameter is hidden, add a '#' to the beginning of the value
- *
- * @return array
- */
- public static function getPersonalBackends() {
-
- // Check whether the user has permissions to add personal storage backends
- // return an empty array if this is not the case
- if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') !== 'yes') {
- return array();
- }
-
- $backEnds = self::getBackends();
-
- // Remove local storage and other disabled storages
- unset($backEnds['\OC\Files\Storage\Local']);
-
- $allowedBackEnds = explode(',', OCP\Config::getAppValue('files_external', 'user_mounting_backends', ''));
- foreach ($backEnds as $backend => $null) {
- if (!in_array($backend, $allowedBackEnds)) {
- unset($backEnds[$backend]);
- }
- }
-
- return $backEnds;
- }
-
/**
* Get the system mount points
* The returned array is not in the same format as getUserMountPoints()
@@ -349,7 +267,7 @@ class OC_Mount_Config {
*/
public static function getSystemMountPoints() {
$mountPoints = self::readData();
- $backends = self::getBackends();
+ $backendService = self::$appContainer->query('\OCA\Files_External\Service\BackendService');
$system = array();
if (isset($mountPoints[self::MOUNT_TYPE_GROUP])) {
foreach ($mountPoints[self::MOUNT_TYPE_GROUP] as $group => $mounts) {
@@ -358,9 +276,10 @@ class OC_Mount_Config {
if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
$mount['class'] = '\OC\Files\Storage\\' . substr($mount['class'], 15);
}
+ $backend = $backendService->getBackend($mount['class']);
$mount['options'] = self::decryptPasswords($mount['options']);
if (!isset($mount['priority'])) {
- $mount['priority'] = $backends[$mount['class']]['priority'];
+ $mount['priority'] = $backend->getPriority();
}
// Remove '/$user/files/' from mount point
$mountPoint = substr($mountPoint, 13);
@@ -368,7 +287,7 @@ class OC_Mount_Config {
$config = array(
'class' => $mount['class'],
'mountpoint' => $mountPoint,
- 'backend' => $backends[$mount['class']]['backend'],
+ 'backend' => $backend->getText(),
'priority' => $mount['priority'],
'options' => $mount['options'],
'applicable' => array('groups' => array($group), 'users' => array())
@@ -401,16 +320,17 @@ class OC_Mount_Config {
if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
$mount['class'] = '\OC\Files\Storage\\' . substr($mount['class'], 15);
}
+ $backend = $backendService->getBackend($mount['class']);
$mount['options'] = self::decryptPasswords($mount['options']);
if (!isset($mount['priority'])) {
- $mount['priority'] = $backends[$mount['class']]['priority'];
+ $mount['priority'] = $backend->getPriority();
}
// Remove '/$user/files/' from mount point
$mountPoint = substr($mountPoint, 13);
$config = array(
'class' => $mount['class'],
'mountpoint' => $mountPoint,
- 'backend' => $backends[$mount['class']]['backend'],
+ 'backend' => $backend->getText(),
'priority' => $mount['priority'],
'options' => $mount['options'],
'applicable' => array('groups' => array(), 'users' => array($user))
@@ -447,7 +367,7 @@ class OC_Mount_Config {
*/
public static function getPersonalMountPoints() {
$mountPoints = self::readData(OCP\User::getUser());
- $backEnds = self::getBackends();
+ $backendService = self::$appContainer->query('\OCA\Files_External\Service\BackendService');
$uid = OCP\User::getUser();
$personal = array();
if (isset($mountPoints[self::MOUNT_TYPE_USER][$uid])) {
@@ -456,12 +376,13 @@ class OC_Mount_Config {
if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
$mount['class'] = '\OC\Files\Storage\\' . substr($mount['class'], 15);
}
+ $backend = $backendService->getBackend($mount['class']);
$mount['options'] = self::decryptPasswords($mount['options']);
$config = array(
'class' => $mount['class'],
// Remove '/uid/files/' from mount point
'mountpoint' => substr($mountPoint, strlen($uid) + 8),
- 'backend' => $backEnds[$mount['class']]['backend'],
+ 'backend' => $backend->getText(),
'options' => $mount['options']
);
if (isset($mount['id'])) {
@@ -535,7 +456,7 @@ class OC_Mount_Config {
$applicable,
$isPersonal = false,
$priority = null) {
- $backends = self::getBackends();
+ $backendService = self::$appContainer->query('\OCA\Files_External\Service\BackendService');
$mountPoint = OC\Files\Filesystem::normalizePath($mountPoint);
$relMountPoint = $mountPoint;
if ($mountPoint === '' || $mountPoint === '/') {
@@ -543,15 +464,15 @@ class OC_Mount_Config {
return false;
}
- if (!isset($backends[$class])) {
+ $backend = $backendService->getBackend($class);
+ if (!isset($backend)) {
// invalid backend
return false;
}
if ($isPersonal) {
// Verify that the mount point applies for the current user
// Prevent non-admin users from mounting local storage and other disabled backends
- $allowed_backends = self::getPersonalBackends();
- if ($applicable != OCP\User::getUser() || !isset($allowed_backends[$class])) {
+ if ($applicable != OCP\User::getUser() || !$backend->isVisibleFor(BackendConfig::VISIBILITY_PERSONAL)) {
return false;
}
$mountPoint = '/' . $applicable . '/files/' . ltrim($mountPoint, '/');
@@ -578,13 +499,8 @@ class OC_Mount_Config {
// Set default priority if none set
if (!isset($mountPoints[$mountType][$applicable][$mountPoint]['priority'])) {
- if (isset($backends[$class]['priority'])) {
- $mountPoints[$mountType][$applicable][$mountPoint]['priority']
- = $backends[$class]['priority'];
- } else {
- $mountPoints[$mountType][$applicable][$mountPoint]['priority']
- = 100;
- }
+ $mountPoints[$mountType][$applicable][$mountPoint]['priority']
+ = $backend->getPriority();
}
self::writeData($isPersonal ? OCP\User::getUser() : null, $mountPoints);
@@ -721,74 +637,35 @@ class OC_Mount_Config {
}
/**
- * check dependencies
+ * Get backend dependency message
+ * TODO: move into AppFramework along with templates
+ *
+ * @param BackendConfig[] $backends
+ * @return string
*/
- public static function checkDependencies() {
- $dependencies = array();
- foreach (OC_Mount_Config::$backends as $class => $backend) {
- if (isset($backend['has_dependencies']) and $backend['has_dependencies'] === true) {
- $result = $class::checkDependencies();
- if ($result !== true) {
- if (!is_array($result)) {
- $result = array($result);
- }
- foreach ($result as $key => $value) {
- if (is_numeric($key)) {
- OC_Mount_Config::addDependency($dependencies, $value, $backend['backend']);
- } else {
- OC_Mount_Config::addDependency($dependencies, $key, $backend['backend'], $value);
- }
- }
- }
- }
- }
-
- if (count($dependencies) > 0) {
- return OC_Mount_Config::generateDependencyMessage($dependencies);
- }
- return '';
- }
-
- private static function addDependency(&$dependencies, $module, $backend, $message = null) {
- if (!isset($dependencies[$module])) {
- $dependencies[$module] = array();
- }
-
- if ($message === null) {
- $dependencies[$module][] = $backend;
- } else {
- $dependencies[$module][] = array('backend' => $backend, 'message' => $message);
- }
- }
-
- private static function generateDependencyMessage($dependencies) {
+ public static function dependencyMessage($backends) {
$l = new \OC_L10N('files_external');
- $dependencyMessage = '';
- foreach ($dependencies as $module => $backends) {
- $dependencyGroup = array();
- foreach ($backends as $backend) {
- if (is_array($backend)) {
- $dependencyMessage .= '<br />' . $l->t('<b>Note:</b> ') . $backend['message'];
+ $message = '';
+ $dependencyGroups = [];
+
+ foreach ($backends as $backend) {
+ foreach ($backend->checkDependencies() as $dependency) {
+ if ($message = $dependency->getMessage()) {
+ $message .= '<br />' . $l->t('<b>Note:</b> ') . $message;
} else {
- $dependencyGroup[] = $backend;
+ $dependencyGroups[$dependency->getDependency()][] = $backend;
}
}
+ }
- $dependencyGroupCount = count($dependencyGroup);
- if ($dependencyGroupCount > 0) {
- $backends = '';
- for ($i = 0; $i < $dependencyGroupCount; $i++) {
- if ($i > 0 && $i === $dependencyGroupCount - 1) {
- $backends .= ' ' . $l->t('and') . ' ';
- } elseif ($i > 0) {
- $backends .= ', ';
- }
- $backends .= '<i>' . $dependencyGroup[$i] . '</i>';
- }
- $dependencyMessage .= '<br />' . OC_Mount_Config::getSingleDependencyMessage($l, $module, $backends);
- }
+ foreach ($dependencyGroups as $module => $dependants) {
+ $backends = implode(', ', array_map(function($backend) {
+ return '<i>' . $backend->getText() . '</i>';
+ }, $dependants));
+ $message .= '<br />' . OC_Mount_Config::getSingleDependencyMessage($l, $module, $backends);
}
- return $dependencyMessage;
+
+ return $message;
}
/**
diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php
index b5c2ba4fc92..6956de1e748 100644
--- a/apps/files_external/lib/config/configadapter.php
+++ b/apps/files_external/lib/config/configadapter.php
@@ -24,14 +24,23 @@ namespace OCA\Files_External\Config;
use OC\Files\Mount\MountPoint;
use OCP\Files\Storage\IStorageFactory;
-use OCA\Files_External\PersonalMount;
+use OCA\Files_External\Lib\PersonalMount;
use OCP\Files\Config\IMountProvider;
use OCP\IUser;
+use OCA\Files_external\Service\UserStoragesService;
/**
* Make the old files_external config work with the new public mount config api
*/
class ConfigAdapter implements IMountProvider {
+
+ /**
+ * @param UserStoragesService $userStoragesService
+ */
+ public function __construct(UserStoragesService $userStoragesService) {
+ $this->userStoragesService = $userStoragesService;
+ }
+
/**
* Get all mountpoints applicable for the user
*
@@ -49,7 +58,8 @@ class ConfigAdapter implements IMountProvider {
}
$mountOptions = isset($options['mountOptions']) ? $options['mountOptions'] : [];
if (isset($options['personal']) && $options['personal']) {
- $mounts[] = new PersonalMount($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
+ $mount = new PersonalMount($this->userStoragesService, $options['id'], $options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
+ $mounts[] = $mount;
} else {
$mounts[] = new MountPoint($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
}
diff --git a/apps/files_external/lib/definitionparameter.php b/apps/files_external/lib/definitionparameter.php
new file mode 100644
index 00000000000..4b560908b69
--- /dev/null
+++ b/apps/files_external/lib/definitionparameter.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+/**
+ * Parameter for an external storage definition
+ */
+class DefinitionParameter implements \JsonSerializable {
+
+ /** Value constants */
+ const VALUE_TEXT = 0;
+ const VALUE_BOOLEAN = 1;
+ const VALUE_PASSWORD = 2;
+ const VALUE_HIDDEN = 3;
+
+ /** Flag constants */
+ const FLAG_NONE = 0;
+ const FLAG_OPTIONAL = 1;
+
+ /** @var string name of parameter */
+ private $name;
+
+ /** @var string human-readable parameter text */
+ private $text;
+
+ /** @var int value type, see self::VALUE_* constants */
+ private $type = self::VALUE_TEXT;
+
+ /** @var int flags, see self::FLAG_* constants */
+ private $flags = self::FLAG_NONE;
+
+ /**
+ * @param string $name
+ * @param string $text
+ */
+ public function __construct($name, $text) {
+ $this->name = $name;
+ $this->text = $text;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * Get value type
+ *
+ * @return int
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * Set value type
+ *
+ * @param int $type
+ * @return self
+ */
+ public function setType($type) {
+ $this->type = $type;
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getFlags() {
+ return $this->flags;
+ }
+
+ /**
+ * @param int $flags
+ * @return self
+ */
+ public function setFlags($flags) {
+ $this->flags = $flags;
+ return $this;
+ }
+
+ /**
+ * @param int $flag
+ * @return self
+ */
+ public function setFlag($flag) {
+ $this->flags |= $flag;
+ return $this;
+ }
+
+ /**
+ * @param int $flag
+ * @return bool
+ */
+ public function isFlagSet($flag) {
+ return (bool) $this->flags & $flag;
+ }
+
+ /**
+ * Serialize into JSON for client-side JS
+ *
+ * @return string
+ */
+ public function jsonSerialize() {
+ $prefix = '';
+ switch ($this->getType()) {
+ case self::VALUE_BOOLEAN:
+ $prefix = '!';
+ break;
+ case self::VALUE_PASSWORD:
+ $prefix = '*';
+ break;
+ case self::VALUE_HIDDEN:
+ $prefix = '#';
+ break;
+ }
+
+ switch ($this->getFlags()) {
+ case self::FLAG_OPTIONAL:
+ $prefix = '&' . $prefix;
+ break;
+ }
+
+ return $prefix . $this->getText();
+ }
+
+ /**
+ * Validate a parameter value against this
+ *
+ * @param mixed $value Value to check
+ * @return bool success
+ */
+ public function validateValue($value) {
+ if ($this->getFlags() & self::FLAG_OPTIONAL) {
+ return true;
+ }
+ switch ($this->getType()) {
+ case self::VALUE_BOOLEAN:
+ if (!is_bool($value)) {
+ return false;
+ }
+ break;
+ default:
+ if (empty($value)) {
+ return false;
+ }
+ break;
+ }
+ return true;
+ }
+}
diff --git a/apps/files_external/lib/dependencytrait.php b/apps/files_external/lib/dependencytrait.php
new file mode 100644
index 00000000000..116421eab14
--- /dev/null
+++ b/apps/files_external/lib/dependencytrait.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+use \OCA\Files_External\Lib\MissingDependency;
+
+/**
+ * Trait for objects that have dependencies for use
+ */
+trait DependencyTrait {
+
+ /** @var callable|null dependency check */
+ private $dependencyCheck = null;
+
+ /**
+ * @return bool
+ */
+ public function hasDependencies() {
+ return !is_null($this->dependencyCheck);
+ }
+
+ /**
+ * @param callable $dependencyCheck
+ * @return self
+ */
+ public function setDependencyCheck(callable $dependencyCheck) {
+ $this->dependencyCheck = $dependencyCheck;
+ return $this;
+ }
+
+ /**
+ * Check if object is valid for use
+ *
+ * @return MissingDependency[] Unsatisfied dependencies
+ */
+ public function checkDependencies() {
+ $ret = [];
+
+ if ($this->hasDependencies()) {
+ $result = call_user_func($this->dependencyCheck);
+ if ($result !== true) {
+ if (!is_array($result)) {
+ $result = [$result];
+ }
+ foreach ($result as $key => $value) {
+ if (!($value instanceof MissingDependency)) {
+ $module = null;
+ $message = null;
+ if (is_numeric($key)) {
+ $module = $value;
+ } else {
+ $module = $key;
+ $message = $value;
+ }
+ $value = new MissingDependency($module, $this);
+ $value->setMessage($message);
+ }
+ $ret[] = $value;
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+}
+
diff --git a/apps/files_external/lib/frontenddefinitiontrait.php b/apps/files_external/lib/frontenddefinitiontrait.php
new file mode 100644
index 00000000000..4b826372d2f
--- /dev/null
+++ b/apps/files_external/lib/frontenddefinitiontrait.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+use \OCA\Files_External\Lib\DefinitionParameter;
+use \OCA\Files_External\Lib\StorageConfig;
+
+/**
+ * Trait for objects that have a frontend representation
+ */
+trait FrontendDefinitionTrait {
+
+ /** @var string human-readable mechanism name */
+ private $text;
+
+ /** @var DefinitionParameter[] parameters for mechanism */
+ private $parameters = [];
+
+ /** @var string|null custom JS */
+ private $customJs = null;
+
+ /**
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * @param string $text
+ * @return self
+ */
+ public function setText($text) {
+ $this->text = $text;
+ return $this;
+ }
+
+ /**
+ * @param FrontendDefinitionTrait $a
+ * @param FrontendDefinitionTrait $b
+ * @return int
+ */
+ public static function lexicalCompare(FrontendDefinitionTrait $a, FrontendDefinitionTrait $b) {
+ return strcmp($a->getText(), $b->getText());
+ }
+
+ /**
+ * @return DefinitionParameter[]
+ */
+ public function getParameters() {
+ return $this->parameters;
+ }
+
+ /**
+ * @param DefinitionParameter[] $parameters
+ * @return self
+ */
+ public function addParameters(array $parameters) {
+ foreach ($parameters as $parameter) {
+ $this->addParameter($parameter);
+ }
+ return $this;
+ }
+
+ /**
+ * @param DefinitionParameter $parameter
+ * @return self
+ */
+ public function addParameter(DefinitionParameter $parameter) {
+ $this->parameters[$parameter->getName()] = $parameter;
+ return $this;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getCustomJs() {
+ return $this->customJs;
+ }
+
+ /**
+ * @param string $custom
+ * @return self
+ */
+ public function setCustomJs($custom) {
+ $this->customJs = $custom;
+ return $this;
+ }
+
+ /**
+ * Serialize into JSON for client-side JS
+ *
+ * @return array
+ */
+ public function jsonSerializeDefinition() {
+ $configuration = [];
+ foreach ($this->getParameters() as $parameter) {
+ $configuration[$parameter->getName()] = $parameter;
+ }
+
+ $data = [
+ 'name' => $this->getText(),
+ 'configuration' => $configuration,
+ ];
+ if (isset($this->customJs)) {
+ $data['custom'] = $this->getCustomJs();
+ }
+ return $data;
+ }
+
+ /**
+ * Check if parameters are satisfied in a StorageConfig
+ *
+ * @param StorageConfig $storage
+ * @return bool
+ */
+ public function validateStorageDefinition(StorageConfig $storage) {
+ $options = $storage->getBackendOptions();
+ foreach ($this->getParameters() as $name => $parameter) {
+ $value = isset($options[$name]) ? $options[$name] : null;
+ if (!$parameter->validateValue($value)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/apps/files_external/lib/missingdependency.php b/apps/files_external/lib/missingdependency.php
new file mode 100644
index 00000000000..9b25aeacc9b
--- /dev/null
+++ b/apps/files_external/lib/missingdependency.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+/**
+ * External storage backend dependency
+ */
+class MissingDependency {
+
+ /** @var string */
+ private $dependency;
+
+ /** @var string|null Custom message */
+ private $message = null;
+
+ /**
+ * @param string $dependency
+ */
+ public function __construct($dependency) {
+ $this->dependency = $dependency;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDependency() {
+ return $this->dependency;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getMessage() {
+ return $this->message;
+ }
+
+ /**
+ * @param string $message
+ * @return self
+ */
+ public function setMessage($message) {
+ $this->message = $message;
+ return $this;
+ }
+}
diff --git a/apps/files_external/lib/personalmount.php b/apps/files_external/lib/personalmount.php
index bbffc958641..d177f1a1ad0 100644
--- a/apps/files_external/lib/personalmount.php
+++ b/apps/files_external/lib/personalmount.php
@@ -20,15 +20,45 @@
*
*/
-namespace OCA\Files_External;
+namespace OCA\Files_External\Lib;
use OC\Files\Mount\MountPoint;
use OC\Files\Mount\MoveableMount;
+use OCA\Files_External\Service\UserStoragesService;
/**
* Person mount points can be moved by the user
*/
class PersonalMount extends MountPoint implements MoveableMount {
+ /** @var UserStoragesService */
+ protected $storagesService;
+
+ /** @var int */
+ protected $storageId;
+
+ /**
+ * @param UserStoragesService $storagesService
+ * @param int $storageId
+ * @param string|\OC\Files\Storage\Storage $storage
+ * @param string $mountpoint
+ * @param array $arguments (optional) configuration for the storage backend
+ * @param \OCP\Files\Storage\IStorageFactory $loader
+ * @param array $mountOptions mount specific options
+ */
+ public function __construct(
+ UserStoragesService $storagesService,
+ $storageId,
+ $storage,
+ $mountpoint,
+ $arguments = null,
+ $loader = null,
+ $mountOptions = null
+ ) {
+ parent::__construct($storage, $mountpoint, $arguments, $loader, $mountOptions);
+ $this->storagesService = $storagesService;
+ $this->storageId = $storageId;
+ }
+
/**
* Move the mount point to $target
*
@@ -36,9 +66,13 @@ class PersonalMount extends MountPoint implements MoveableMount {
* @return bool
*/
public function moveMount($target) {
- $result = \OC_Mount_Config::movePersonalMountPoint($this->getMountPoint(), $target, \OC_Mount_Config::MOUNT_TYPE_USER);
+ $storage = $this->storagesService->getStorage($this->storageId);
+ // remove "/$user/files" prefix
+ $targetParts = explode('/', trim($target, '/'), 3);
+ $storage->setMountPoint($targetParts[2]);
+ $this->storagesService->updateStorage($storage);
$this->setMountPoint($target);
- return $result;
+ return true;
}
/**
@@ -47,8 +81,7 @@ class PersonalMount extends MountPoint implements MoveableMount {
* @return bool
*/
public function removeMount() {
- $user = \OCP\User::getUser();
- $relativeMountPoint = substr($this->getMountPoint(), strlen('/' . $user . '/files/'));
- return \OC_Mount_Config::removeMountPoint($relativeMountPoint, \OC_Mount_Config::MOUNT_TYPE_USER, $user , true);
+ $this->storagesService->removeStorage($this->storageId);
+ return true;
}
}
diff --git a/apps/files_external/lib/prioritytrait.php b/apps/files_external/lib/prioritytrait.php
new file mode 100644
index 00000000000..22f9fe275d8
--- /dev/null
+++ b/apps/files_external/lib/prioritytrait.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+use \OCA\Files_External\Service\BackendService;
+
+/**
+ * Trait to implement priority mechanics for a configuration class
+ */
+trait PriorityTrait {
+
+ /** @var int initial priority */
+ protected $priority = BackendService::PRIORITY_DEFAULT;
+
+ /**
+ * @return int
+ */
+ public function getPriority() {
+ return $this->priority;
+ }
+
+ /**
+ * @param int $priority
+ * @return self
+ */
+ public function setPriority($priority) {
+ $this->priority = $priority;
+ return $this;
+ }
+
+ /**
+ * @param PriorityTrait $a
+ * @param PriorityTrait $b
+ * @return int
+ */
+ public static function priorityCompare(PriorityTrait $a, PriorityTrait $b) {
+ return ($a->getPriority() - $b->getPriority());
+ }
+
+}
+
diff --git a/apps/files_external/lib/storageconfig.php b/apps/files_external/lib/storageconfig.php
index 92c27701d80..cf8271ff4eb 100644
--- a/apps/files_external/lib/storageconfig.php
+++ b/apps/files_external/lib/storageconfig.php
@@ -21,6 +21,8 @@
namespace OCA\Files_external\Lib;
+use \OCA\Files_External\Lib\Backend\Backend;
+
/**
* External storage configuration
*/
@@ -34,11 +36,11 @@ class StorageConfig implements \JsonSerializable {
private $id;
/**
- * Backend class name
+ * Backend
*
- * @var string
+ * @var Backend
*/
- private $backendClass;
+ private $backend;
/**
* Backend options
@@ -138,21 +140,17 @@ class StorageConfig implements \JsonSerializable {
}
/**
- * Returns the external storage backend class name
- *
- * @return string external storage backend class name
+ * @return Backend
*/
- public function getBackendClass() {
- return $this->backendClass;
+ public function getBackend() {
+ return $this->backend;
}
/**
- * Sets the external storage backend class name
- *
- * @param string external storage backend class name
+ * @param Backend
*/
- public function setBackendClass($backendClass) {
- $this->backendClass = $backendClass;
+ public function setBackend(Backend $backend) {
+ $this->backend= $backend;
}
/**
@@ -174,6 +172,25 @@ class StorageConfig implements \JsonSerializable {
}
/**
+ * @param string $key
+ * @return mixed
+ */
+ public function getBackendOption($key) {
+ if (isset($this->backendOptions[$key])) {
+ return $this->backendOptions[$key];
+ }
+ return null;
+ }
+
+ /**
+ * @param string $key
+ * @param mixed $value
+ */
+ public function setBackendOption($key, $value) {
+ $this->backendOptions[$key] = $value;
+ }
+
+ /**
* Returns the mount priority
*
* @return int priority
@@ -283,7 +300,7 @@ class StorageConfig implements \JsonSerializable {
$result['id'] = $this->id;
}
$result['mountPoint'] = $this->mountPoint;
- $result['backendClass'] = $this->backendClass;
+ $result['backendClass'] = $this->backend->getClass();
$result['backendOptions'] = $this->backendOptions;
if (!is_null($this->priority)) {
$result['priority'] = $this->priority;
diff --git a/apps/files_external/lib/storagemodifiertrait.php b/apps/files_external/lib/storagemodifiertrait.php
new file mode 100644
index 00000000000..f78116103db
--- /dev/null
+++ b/apps/files_external/lib/storagemodifiertrait.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+use \OCP\Files\Storage;
+use \OCA\Files_External\Lib\StorageConfig;
+
+/**
+ * Trait for objects that can modify StorageConfigs and wrap Storages
+ */
+trait StorageModifierTrait {
+
+ /**
+ * Modify a StorageConfig parameters
+ *
+ * @param StorageConfig $storage
+ */
+ public function manipulateStorageConfig(StorageConfig &$storage) {
+ }
+
+ /**
+ * Wrap a Storage if necessary
+ *
+ * @param Storage $storage
+ * @return Storage
+ */
+ public function wrapStorage(Storage $storage) {
+ return $storage;
+ }
+
+}
+
diff --git a/apps/files_external/lib/visibilitytrait.php b/apps/files_external/lib/visibilitytrait.php
new file mode 100644
index 00000000000..06c95dd70c9
--- /dev/null
+++ b/apps/files_external/lib/visibilitytrait.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ *
+ * @copyright Copyright (c) 2015, 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;
+
+use \OCA\Files_External\Service\BackendService;
+
+/**
+ * Trait to implement visibility mechanics for a configuration class
+ */
+trait VisibilityTrait {
+
+ /** @var int visibility */
+ protected $visibility = BackendService::VISIBILITY_DEFAULT;
+
+ /** @var int allowed visibilities */
+ protected $allowedVisibility = BackendService::VISIBILITY_DEFAULT;
+
+ /**
+ * @return int
+ */
+ public function getVisibility() {
+ return $this->visibility;
+ }
+
+ /**
+ * Check if the backend is visible for a user type
+ *
+ * @param int $visibility
+ * @return bool
+ */
+ public function isVisibleFor($visibility) {
+ if ($this->visibility & $visibility) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param int $visibility
+ * @return self
+ */
+ public function setVisibility($visibility) {
+ $this->visibility = $visibility;
+ $this->allowedVisibility |= $visibility;
+ return $this;
+ }
+
+ /**
+ * @param int $visibility
+ * @return self
+ */
+ public function addVisibility($visibility) {
+ return $this->setVisibility($this->visibility | $visibility);
+ }
+
+ /**
+ * @param int $visibility
+ * @return self
+ */
+ public function removeVisibility($visibility) {
+ return $this->setVisibility($this->visibility & ~$visibility);
+ }
+
+ /**
+ * @return int
+ */
+ public function getAllowedVisibility() {
+ return $this->allowedVisibility;
+ }
+
+ /**
+ * Check if the backend is allowed to be visible for a user type
+ *
+ * @param int $allowedVisibility
+ * @return bool
+ */
+ public function isAllowedVisibleFor($allowedVisibility) {
+ if ($this->allowedVisibility & $allowedVisibility) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param int $allowedVisibility
+ * @return self
+ */
+ public function setAllowedVisibility($allowedVisibility) {
+ $this->allowedVisibility = $allowedVisibility;
+ $this->visibility &= $allowedVisibility;
+ return $this;
+ }
+
+ /**
+ * @param int $allowedVisibility
+ * @return self
+ */
+ public function addAllowedVisibility($allowedVisibility) {
+ return $this->setAllowedVisibility($this->allowedVisibility | $allowedVisibility);
+ }
+
+ /**
+ * @param int $allowedVisibility
+ * @return self
+ */
+ public function removeAllowedVisibility($allowedVisibility) {
+ return $this->setAllowedVisibility($this->allowedVisibility & ~$allowedVisibility);
+ }
+
+}
diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php
index 1ac0f65a1f0..e204cdbeb99 100644
--- a/apps/files_external/personal.php
+++ b/apps/files_external/personal.php
@@ -24,34 +24,20 @@
*
*/
-OCP\Util::addScript('files_external', 'settings');
-OCP\Util::addStyle('files_external', 'settings');
-$backends = OC_Mount_Config::getPersonalBackends();
+use \OCA\Files_External\Service\BackendService;
-$mounts = OC_Mount_Config::getPersonalMountPoints();
-$hasId = true;
-foreach ($mounts as $mount) {
- if (!isset($mount['id'])) {
- // some mount points are missing ids
- $hasId = false;
- break;
- }
-}
+$app = new \OCA\Files_external\Appinfo\Application();
+$appContainer = $app->getContainer();
+$backendService = $appContainer->query('OCA\Files_External\Service\BackendService');
+$userStoragesService = $appContainer->query('OCA\Files_external\Service\UserStoragesService');
-if (!$hasId) {
- $service = new \OCA\Files_external\Service\UserStoragesService(\OC::$server->getUserSession());
- // this will trigger the new storage code which will automatically
- // generate storage config ids
- $service->getAllStorages();
- // re-read updated config
- $mounts = OC_Mount_Config::getPersonalMountPoints();
- // TODO: use the new storage config format in the template
-}
+OCP\Util::addScript('files_external', 'settings');
+OCP\Util::addStyle('files_external', 'settings');
$tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('encryptionEnabled', \OC::$server->getEncryptionManager()->isEnabled());
$tmpl->assign('isAdminPage', false);
-$tmpl->assign('mounts', $mounts);
-$tmpl->assign('dependencies', OC_Mount_Config::checkDependencies());
-$tmpl->assign('backends', $backends);
+$tmpl->assign('storages', $userStoragesService->getAllStorages());
+$tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends()));
+$tmpl->assign('backends', $backendService->getBackendsVisibleFor(BackendService::VISIBILITY_PERSONAL));
return $tmpl->fetchPage();
diff --git a/apps/files_external/service/backendservice.php b/apps/files_external/service/backendservice.php
new file mode 100644
index 00000000000..f5859bc7272
--- /dev/null
+++ b/apps/files_external/service/backendservice.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ *
+ * @copyright Copyright (c) 2015, 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\Service;
+
+use \OCP\IConfig;
+
+use \OCA\Files_External\Lib\Backend\Backend;
+
+/**
+ * Service class to manage backend definitions
+ */
+class BackendService {
+
+ /** Visibility constants for VisibilityTrait */
+ const VISIBILITY_NONE = 0;
+ const VISIBILITY_PERSONAL = 1;
+ const VISIBILITY_ADMIN = 2;
+ //const VISIBILITY_ALIENS = 4;
+
+ const VISIBILITY_DEFAULT = 3; // PERSONAL | ADMIN
+
+ /** Priority constants for PriorityTrait */
+ const PRIORITY_DEFAULT = 100;
+
+ /** @var IConfig */
+ protected $config;
+
+ /** @var bool */
+ private $userMountingAllowed = true;
+
+ /** @var string[] */
+ private $userMountingBackends = [];
+
+ /** @var Backend[] */
+ private $backends = [];
+
+ /**
+ * @param IConfig $config
+ */
+ public function __construct(
+ IConfig $config
+ ) {
+ $this->config = $config;
+
+ // 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', '')
+ );
+ }
+
+ /**
+ * Register a backend
+ *
+ * @param Backend $backend
+ */
+ public function registerBackend(Backend $backend) {
+ if (!$this->isAllowedUserBackend($backend)) {
+ $backend->removeVisibility(BackendService::VISIBILITY_PERSONAL);
+ }
+ $this->backends[$backend->getClass()] = $backend;
+ }
+
+ /**
+ * @param Backend[] $backends
+ */
+ public function registerBackends(array $backends) {
+ foreach ($backends as $backend) {
+ $this->registerBackend($backend);
+ }
+ }
+
+ /**
+ * Get all backends
+ *
+ * @return Backend[]
+ */
+ public function getBackends() {
+ return $this->backends;
+ }
+
+ /**
+ * Get all available backends
+ *
+ * @return Backend[]
+ */
+ public function getAvailableBackends() {
+ return array_filter($this->getBackends(), function($backend) {
+ return empty($backend->checkDependencies());
+ });
+ }
+
+ /**
+ * Get backends visible for $visibleFor
+ *
+ * @param int $visibleFor
+ * @return Backend[]
+ */
+ public function getBackendsVisibleFor($visibleFor) {
+ return array_filter($this->getAvailableBackends(), function($backend) use ($visibleFor) {
+ return $backend->isVisibleFor($visibleFor);
+ });
+ }
+
+ /**
+ * Get backends allowed to be visible for $visibleFor
+ *
+ * @param int $visibleFor
+ * @return Backend[]
+ */
+ public function getBackendsAllowedVisibleFor($visibleFor) {
+ return array_filter($this->getAvailableBackends(), function($backend) use ($visibleFor) {
+ return $backend->isAllowedVisibleFor($visibleFor);
+ });
+ }
+
+ /**
+ * @param string $class Backend class name
+ * @return Backend|null
+ */
+ public function getBackend($class) {
+ if (isset($this->backends[$class])) {
+ return $this->backends[$class];
+ }
+ return null;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isUserMountingAllowed() {
+ return $this->userMountingAllowed;
+ }
+
+ /**
+ * Check a backend if a user is allowed to mount it
+ *
+ * @param Backend $backend
+ * @return bool
+ */
+ protected function isAllowedUserBackend(Backend $backend) {
+ if ($this->userMountingAllowed &&
+ in_array($backend->getClass(), $this->userMountingBackends)
+ ) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/apps/files_external/service/storagesservice.php b/apps/files_external/service/storagesservice.php
index 930f994455e..5f11d9ace68 100644
--- a/apps/files_external/service/storagesservice.php
+++ b/apps/files_external/service/storagesservice.php
@@ -28,12 +28,23 @@ use \OC\Files\Filesystem;
use \OCA\Files_external\Lib\StorageConfig;
use \OCA\Files_external\NotFoundException;
+use \OCA\Files_External\Service\BackendService;
/**
* Service class to manage external storages
*/
abstract class StoragesService {
+ /** @var BackendService */
+ protected $backendService;
+
+ /**
+ * @param BackendService $backendService
+ */
+ public function __construct(BackendService $backendService) {
+ $this->backendService = $backendService;
+ }
+
/**
* Read legacy config data
*
@@ -60,14 +71,17 @@ abstract class StoragesService {
$applicable,
$storageOptions
) {
- $storageConfig->setBackendClass($storageOptions['class']);
+ $backend = $this->backendService->getBackend($storageOptions['class']);
+ $storageConfig->setBackend($backend);
+
$storageConfig->setBackendOptions($storageOptions['options']);
if (isset($storageOptions['mountOptions'])) {
$storageConfig->setMountOptions($storageOptions['mountOptions']);
}
- if (isset($storageOptions['priority'])) {
- $storageConfig->setPriority($storageOptions['priority']);
+ if (!isset($storageOptions['priority'])) {
+ $storageOptions['priority'] = $backend->getPriority();
}
+ $storageConfig->setPriority($storageOptions['priority']);
if ($mountType === \OC_Mount_Config::MOUNT_TYPE_USER) {
$applicableUsers = $storageConfig->getApplicableUsers();
@@ -222,7 +236,7 @@ abstract class StoragesService {
$options = [
'id' => $storageConfig->getId(),
- 'class' => $storageConfig->getBackendClass(),
+ 'class' => $storageConfig->getBackend()->getClass(),
'options' => $storageConfig->getBackendOptions(),
];
@@ -297,6 +311,52 @@ abstract class StoragesService {
}
/**
+ * Create a storage from its parameters
+ *
+ * @param string $mountPoint storage mount point
+ * @param string $backendClass backend class name
+ * @param array $backendOptions backend-specific options
+ * @param array|null $mountOptions mount-specific options
+ * @param array|null $applicableUsers users for which to mount the storage
+ * @param array|null $applicableGroups groups for which to mount the storage
+ * @param int|null $priority priority
+ *
+ * @return StorageConfig
+ */
+ public function createStorage(
+ $mountPoint,
+ $backendClass,
+ $backendOptions,
+ $mountOptions = null,
+ $applicableUsers = null,
+ $applicableGroups = null,
+ $priority = null
+ ) {
+ $backend = $this->backendService->getBackend($backendClass);
+ if (!$backend) {
+ throw new \InvalidArgumentException('Unable to get backend for backend class '.$backendClass);
+ }
+ $newStorage = new StorageConfig();
+ $newStorage->setMountPoint($mountPoint);
+ $newStorage->setBackend($backend);
+ $newStorage->setBackendOptions($backendOptions);
+ if (isset($mountOptions)) {
+ $newStorage->setMountOptions($mountOptions);
+ }
+ if (isset($applicableUsers)) {
+ $newStorage->setApplicableUsers($applicableUsers);
+ }
+ if (isset($applicableGroups)) {
+ $newStorage->setApplicableGroups($applicableGroups);
+ }
+ if (isset($priority)) {
+ $newStorage->setPriority($priority);
+ }
+
+ return $newStorage;
+ }
+
+ /**
* Triggers the given hook signal for all the applicables given
*
* @param string $signal signal
diff --git a/apps/files_external/service/userstoragesservice.php b/apps/files_external/service/userstoragesservice.php
index 2f2556043fe..7ca911d45fb 100644
--- a/apps/files_external/service/userstoragesservice.php
+++ b/apps/files_external/service/userstoragesservice.php
@@ -26,6 +26,7 @@ use \OC\Files\Filesystem;
use \OCA\Files_external\Lib\StorageConfig;
use \OCA\Files_external\NotFoundException;
+use \OCA\Files_External\Service\BackendService;
/**
* Service class to manage user external storages
@@ -43,12 +44,15 @@ class UserStoragesService extends StoragesService {
/**
* Create a user storages service
*
+ * @param BackendService $backendService
* @param IUserSession $userSession user session
*/
public function __construct(
+ BackendService $backendService,
IUserSession $userSession
) {
$this->userSession = $userSession;
+ parent::__construct($backendService);
}
/**
diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php
index 6db68713d98..7c53db4c0dd 100644
--- a/apps/files_external/settings.php
+++ b/apps/files_external/settings.php
@@ -26,54 +26,27 @@
*
*/
+use \OCA\Files_External\Service\BackendService;
+
OC_Util::checkAdminUser();
+$app = new \OCA\Files_external\Appinfo\Application();
+$appContainer = $app->getContainer();
+$backendService = $appContainer->query('OCA\Files_External\Service\BackendService');
+$globalStoragesService = $appContainer->query('OCA\Files_external\Service\GlobalStoragesService');
+
OCP\Util::addScript('files_external', 'settings');
OCP\Util::addStyle('files_external', 'settings');
\OC_Util::addVendorScript('select2/select2');
\OC_Util::addVendorStyle('select2/select2');
-$backends = OC_Mount_Config::getBackends();
-$personal_backends = array();
-$enabled_backends = explode(',', OCP\Config::getAppValue('files_external', 'user_mounting_backends', ''));
-foreach ($backends as $class => $backend)
-{
- if ($class != '\OC\Files\Storage\Local')
- {
- $personal_backends[$class] = array(
- 'backend' => $backend['backend'],
- 'enabled' => in_array($class, $enabled_backends),
- );
- }
-}
-
-$mounts = OC_Mount_Config::getSystemMountPoints();
-$hasId = true;
-foreach ($mounts as $mount) {
- if (!isset($mount['id'])) {
- // some mount points are missing ids
- $hasId = false;
- break;
- }
-}
-
-if (!$hasId) {
- $service = new \OCA\Files_external\Service\GlobalStoragesService();
- // this will trigger the new storage code which will automatically
- // generate storage config ids
- $service->getAllStorages();
- // re-read updated config
- $mounts = OC_Mount_Config::getSystemMountPoints();
- // TODO: use the new storage config format in the template
-}
-
$tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('encryptionEnabled', \OC::$server->getEncryptionManager()->isEnabled());
$tmpl->assign('isAdminPage', true);
-$tmpl->assign('mounts', $mounts);
-$tmpl->assign('backends', $backends);
-$tmpl->assign('personal_backends', $personal_backends);
-$tmpl->assign('dependencies', OC_Mount_Config::checkDependencies());
-$tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes'));
+$tmpl->assign('storages', $globalStoragesService->getAllStorages());
+$tmpl->assign('backends', $backendService->getBackendsVisibleFor(BackendService::VISIBILITY_ADMIN));
+$tmpl->assign('userBackends', $backendService->getBackendsAllowedVisibleFor(BackendService::VISIBILITY_PERSONAL));
+$tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends()));
+$tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed());
return $tmpl->fetchPage();
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index b886c2e1b1b..f931c62eecd 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -1,3 +1,8 @@
+<?php
+ use \OCA\Files_External\Lib\Backend\Backend;
+ use \OCA\Files_External\Lib\DefinitionParameter;
+ use \OCA\Files_External\Service\BackendService;
+?>
<form id="files_external" class="section" data-encryption-enabled="<?php echo $_['encryptionEnabled']?'true': 'false'; ?>">
<h2><?php p($l->t('External Storage')); ?></h2>
<?php if (isset($_['dependencies']) and ($_['dependencies']<>'')) print_unescaped(''.$_['dependencies'].''); ?>
@@ -14,103 +19,149 @@
</tr>
</thead>
<tbody>
- <?php $_['mounts'] = array_merge($_['mounts'], array('' => array('id' => ''))); ?>
- <?php foreach ($_['mounts'] as $mount): ?>
- <tr <?php print_unescaped(isset($mount['mountpoint']) ? 'class="'.OC_Util::sanitizeHTML($mount['class']).'"' : 'id="addMountPoint"'); ?> data-id="<?php p($mount['id']) ?>">
+ <?php foreach ($_['storages'] as $storage): ?>
+ <tr class="<?php p($storage->getBackend()->getClass()); ?>" data-id="<?php p($storage->getId()); ?>">
<td class="status">
<span></span>
</td>
<td class="mountPoint"><input type="text" name="mountPoint"
- value="<?php p(isset($mount['mountpoint']) ? $mount['mountpoint'] : ''); ?>"
- data-mountpoint="<?php p(isset($mount['mountpoint']) ? $mount['mountpoint'] : ''); ?>"
+ value="<?php p(ltrim($storage->getMountPoint(), '/')); ?>"
+ data-mountpoint="<?php p(ltrim($storage->getMountPoint(), '/')); ?>"
placeholder="<?php p($l->t('Folder name')); ?>" />
</td>
- <?php if (!isset($mount['mountpoint'])): ?>
- <td class="backend">
- <select id="selectBackend" class="selectBackend" data-configurations='<?php p(json_encode($_['backends'])); ?>'>
- <option value="" disabled selected
- style="display:none;"><?php p($l->t('Add storage')); ?></option>
- <?php foreach ($_['backends'] as $class => $backend): ?>
- <option value="<?php p($class); ?>"><?php p($backend['backend']); ?></option>
- <?php endforeach; ?>
- </select>
- </td>
- <?php else: ?>
- <td class="backend" data-class="<?php p($mount['class']); ?>"><?php p($mount['backend']); ?>
- </td>
- <?php endif; ?>
- <td class ="configuration">
- <?php if (isset($mount['options'])): ?>
- <?php foreach ($mount['options'] as $parameter => $value): ?>
- <?php if (isset($_['backends'][$mount['class']]['configuration'][$parameter])): ?>
+ <td class="backend" data-class="<?php p($storage->getBackend()->getClass()); ?>"><?php p($storage->getBackend()->getText()); ?>
+ </td>
+ <td class="configuration">
+ <?php $options = $storage->getBackendOptions(); ?>
+ <?php foreach ($storage->getBackend()->getParameters() as $parameter): ?>
+ <?php
+ $value = '';
+ if (isset($options[$parameter->getName()])) {
+ $value = $options[$parameter->getName()];
+ }
+ $placeholder = $parameter->getText();
+ $is_optional = $parameter->isFlagSet(DefinitionParameter::FLAG_OPTIONAL);
+
+ switch ($parameter->getType()) {
+ case DefinitionParameter::VALUE_PASSWORD: ?>
+ <input type="password"
+ <?php if ($is_optional): ?> class="optional"<?php endif; ?>
+ data-parameter="<?php p($parameter->getName()); ?>"
+ value="<?php p($value); ?>"
+ placeholder="<?php p($placeholder); ?>"
+ />
<?php
- $placeholder = $_['backends'][$mount['class']]['configuration'][$parameter];
- $is_optional = FALSE;
- if (strpos($placeholder, '&') === 0) {
- $is_optional = TRUE;
- $placeholder = substr($placeholder, 1);
- }
- ?>
- <?php if (strpos($placeholder, '*') === 0): ?>
- <input type="password"
- <?php if ($is_optional): ?> class="optional"<?php endif; ?>
- data-parameter="<?php p($parameter); ?>"
- value="<?php p($value); ?>"
- placeholder="<?php p(substr($placeholder, 1)); ?>" />
- <?php elseif (strpos($placeholder, '!') === 0): ?>
- <label><input type="checkbox"
- data-parameter="<?php p($parameter); ?>"
- <?php if ($value == 'true'): ?> checked="checked"<?php endif; ?>
- /><?php p(substr($placeholder, 1)); ?></label>
- <?php elseif (strpos($placeholder, '#') === 0): ?>
- <input type="hidden"
- data-parameter="<?php p($parameter); ?>"
- value="<?php p($value); ?>" />
- <?php else: ?>
- <input type="text"
- <?php if ($is_optional): ?> class="optional"<?php endif; ?>
- data-parameter="<?php p($parameter); ?>"
- value="<?php p($value); ?>"
- placeholder="<?php p($placeholder); ?>" />
- <?php endif; ?>
- <?php endif; ?>
- <?php endforeach; ?>
- <?php if (isset($_['backends'][$mount['class']]['custom'])): ?>
- <?php OCP\Util::addScript('files_external', $_['backends'][$mount['class']]['custom']); ?>
- <?php endif; ?>
- <?php endif; ?>
+ break;
+ case DefinitionParameter::VALUE_BOOLEAN: ?>
+ <label>
+ <input type="checkbox"
+ data-parameter="<?php p($parameter->getName()); ?>"
+ <?php if ($value == 'true'): ?> checked="checked"<?php endif; ?>
+ />
+ <?php p($placeholder); ?>
+ </label>
+ <?php
+ break;
+ case DefinitionParameter::VALUE_HIDDEN: ?>
+ <input type="hidden"
+ data-parameter="<?php p($parameter->getName()); ?>"
+ value="<?php p($value); ?>"
+ />
+ <?php
+ break;
+ default: ?>
+ <input type="text"
+ <?php if ($is_optional): ?> class="optional"<?php endif; ?>
+ data-parameter="<?php p($parameter->getName()); ?>"
+ value="<?php p($value); ?>"
+ placeholder="<?php p($placeholder); ?>"
+ />
+ <?php
+ }
+ ?>
+ <?php endforeach; ?>
+ <?php
+ $customJs = $storage->getBackend()->getCustomJs();
+ if (isset($customJs)) {
+ \OCP\Util::addScript('files_external', $customJs);
+ }
+ ?>
</td>
<?php if ($_['isAdminPage']): ?>
- <td class="applicable"
- align="right"
- data-applicable-groups='<?php if (isset($mount['applicable']['groups']))
- print_unescaped(json_encode($mount['applicable']['groups'])); ?>'
- data-applicable-users='<?php if (isset($mount['applicable']['users']))
- print_unescaped(json_encode($mount['applicable']['users'])); ?>'>
- <input type="hidden" class="applicableUsers" style="width:20em;" value=""/>
- </td>
+ <td class="applicable"
+ align="right"
+ data-applicable-groups='<?php print_unescaped(json_encode($storage->getApplicableGroups())); ?>'
+ data-applicable-users='<?php print_unescaped(json_encode($storage->getApplicableUsers())); ?>'>
+ <input type="hidden" class="applicableUsers" style="width:20em;" value=""/>
+ </td>
<?php endif; ?>
- <td class="mountOptionsToggle <?php if (!isset($mount['mountpoint'])) { p('hidden'); } ?>"
- ><img
+ <td class="mountOptionsToggle">
+ <img
class="svg action"
title="<?php p($l->t('Advanced settings')); ?>"
alt="<?php p($l->t('Advanced settings')); ?>"
- src="<?php print_unescaped(image_path('core', 'actions/settings.svg')); ?>" />
- <input type="hidden" class="mountOptions" value="<?php isset($mount['mountOptions']) ? p(json_encode($mount['mountOptions'])) : '' ?>" />
+ src="<?php print_unescaped(image_path('core', 'actions/settings.svg')); ?>"
+ />
+ <input type="hidden" class="mountOptions" value="<?php p(json_encode($storage->getMountOptions())); ?>" />
<?php if ($_['isAdminPage']): ?>
- <?php if (isset($mount['priority'])): ?>
- <input type="hidden" class="priority" value="<?php p($mount['priority']) ?>" />
- <?php endif; ?>
+ <input type="hidden" class="priority" value="<?php p($storage->getPriority()); ?>" />
<?php endif; ?>
</td>
- <td <?php if (isset($mount['mountpoint'])): ?>class="remove"
- <?php else: ?>class="hidden"
- <?php endif ?>><img alt="<?php p($l->t('Delete')); ?>"
- title="<?php p($l->t('Delete')); ?>"
- class="svg action"
- src="<?php print_unescaped(image_path('core', 'actions/delete.svg')); ?>" /></td>
+ <td class="remove">
+ <img alt="<?php p($l->t('Delete')); ?>"
+ title="<?php p($l->t('Delete')); ?>"
+ class="svg action"
+ src="<?php print_unescaped(image_path('core', 'actions/delete.svg')); ?>"
+ />
+ </td>
</tr>
<?php endforeach; ?>
+ <tr id="addMountPoint">
+ <td class="status">
+ <span></span>
+ </td>
+ <td class="mountPoint"><input type="text" name="mountPoint" value=""
+ placeholder="<?php p($l->t('Folder name')); ?>">
+ </td>
+ <td class="backend">
+ <select id="selectBackend" class="selectBackend" data-configurations='<?php p(json_encode($_['backends'])); ?>'>
+ <option value="" disabled selected
+ style="display:none;">
+ <?php p($l->t('Add storage')); ?>
+ </option>
+ <?php
+ $sortedBackends = $_['backends'];
+ uasort($sortedBackends, function($a, $b) {
+ return strcasecmp($a->getText(), $b->getText());
+ });
+ ?>
+ <?php foreach ($sortedBackends as $backend): ?>
+ <option value="<?php p($backend->getClass()); ?>"><?php p($backend->getText()); ?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="configuration"</td>
+ <?php if ($_['isAdminPage']): ?>
+ <td class="applicable" align="right">
+ <input type="hidden" class="applicableUsers" style="width:20em;" value="" />
+ </td>
+ <?php endif; ?>
+ <td class="mountOptionsToggle hidden">
+ <img class="svg action"
+ title="<?php p($l->t('Advanced settings')); ?>"
+ alt="<?php p($l->t('Advanced settings')); ?>"
+ src="<?php print_unescaped(image_path('core', 'actions/settings.svg')); ?>"
+ />
+ <input type="hidden" class="mountOptions" value="" />
+ </td>
+ <td class="hidden">
+ <img class="svg action"
+ alt="<?php p($l->t('Delete')); ?>"
+ title="<?php p($l->t('Delete')); ?>"
+ src="<?php print_unescaped(image_path('core', 'actions/delete.svg')); ?>"
+ />
+ </td>
+ </tr>
</tbody>
</table>
<br />
@@ -123,9 +174,9 @@
<p id="userMountingBackends"<?php if ($_['allowUserMounting'] != 'yes'): ?> class="hidden"<?php endif; ?>>
<?php p($l->t('Allow users to mount the following external storage')); ?><br />
- <?php $i = 0; foreach ($_['personal_backends'] as $class => $backend): ?>
- <input type="checkbox" id="allowUserMountingBackends<?php p($i); ?>" name="allowUserMountingBackends[]" value="<?php p($class); ?>" <?php if ($backend['enabled']) print_unescaped(' checked="checked"'); ?> />
- <label for="allowUserMountingBackends<?php p($i); ?>"><?php p($backend['backend']); ?></label> <br />
+ <?php $i = 0; foreach ($_['userBackends'] as $backend): ?>
+ <input type="checkbox" id="allowUserMountingBackends<?php p($i); ?>" name="allowUserMountingBackends[]" value="<?php p($backend->getClass()); ?>" <?php if ($backend->isVisibleFor(BackendService::VISIBILITY_PERSONAL)) print_unescaped(' checked="checked"'); ?> />
+ <label for="allowUserMountingBackends<?php p($i); ?>"><?php p($backend->getText()); ?></label> <br />
<?php $i++; ?>
<?php endforeach; ?>
</p>
diff --git a/apps/files_external/tests/controller/globalstoragescontrollertest.php b/apps/files_external/tests/controller/globalstoragescontrollertest.php
index fc58743454a..e1bfad8caf6 100644
--- a/apps/files_external/tests/controller/globalstoragescontrollertest.php
+++ b/apps/files_external/tests/controller/globalstoragescontrollertest.php
@@ -28,7 +28,9 @@ use \OCA\Files_external\NotFoundException;
class GlobalStoragesControllerTest extends StoragesControllerTest {
public function setUp() {
parent::setUp();
- $this->service = $this->getMock('\OCA\Files_external\Service\GlobalStoragesService');
+ $this->service = $this->getMockBuilder('\OCA\Files_external\Service\GlobalStoragesService')
+ ->disableOriginalConstructor()
+ ->getMock();
$this->controller = new GlobalStoragesController(
'files_external',
diff --git a/apps/files_external/tests/controller/storagescontrollertest.php b/apps/files_external/tests/controller/storagescontrollertest.php
index 86874ef9786..f3e8c9afbac 100644
--- a/apps/files_external/tests/controller/storagescontrollertest.php
+++ b/apps/files_external/tests/controller/storagescontrollertest.php
@@ -47,11 +47,33 @@ abstract class StoragesControllerTest extends \Test\TestCase {
\OC_Mount_Config::$skipTest = false;
}
+ protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') {
+ $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->method('getStorageClass')
+ ->willReturn($storageClass);
+ $backend->method('getClass')
+ ->willReturn($storageClass);
+ return $backend;
+ }
+
public function testAddStorage() {
+ $backend = $this->getBackendMock();
+ $backend->method('validateStorage')
+ ->willReturn(true);
+ $backend->method('isVisibleFor')
+ ->willReturn(true);
+
$storageConfig = new StorageConfig(1);
$storageConfig->setMountPoint('mount');
+ $storageConfig->setBackend($backend);
+ $storageConfig->setBackendOptions([]);
$this->service->expects($this->once())
+ ->method('createStorage')
+ ->will($this->returnValue($storageConfig));
+ $this->service->expects($this->once())
->method('addStorage')
->will($this->returnValue($storageConfig));
@@ -71,10 +93,21 @@ abstract class StoragesControllerTest extends \Test\TestCase {
}
public function testUpdateStorage() {
+ $backend = $this->getBackendMock();
+ $backend->method('validateStorage')
+ ->willReturn(true);
+ $backend->method('isVisibleFor')
+ ->willReturn(true);
+
$storageConfig = new StorageConfig(1);
$storageConfig->setMountPoint('mount');
+ $storageConfig->setBackend($backend);
+ $storageConfig->setBackendOptions([]);
$this->service->expects($this->once())
+ ->method('createStorage')
+ ->will($this->returnValue($storageConfig));
+ $this->service->expects($this->once())
->method('updateStorage')
->will($this->returnValue($storageConfig));
@@ -106,6 +139,14 @@ abstract class StoragesControllerTest extends \Test\TestCase {
* @dataProvider mountPointNamesProvider
*/
public function testAddOrUpdateStorageInvalidMountPoint($mountPoint) {
+ $storageConfig = new StorageConfig(1);
+ $storageConfig->setMountPoint($mountPoint);
+ $storageConfig->setBackend($this->getBackendMock());
+ $storageConfig->setBackendOptions([]);
+
+ $this->service->expects($this->exactly(2))
+ ->method('createStorage')
+ ->will($this->returnValue($storageConfig));
$this->service->expects($this->never())
->method('addStorage');
$this->service->expects($this->never())
@@ -138,6 +179,9 @@ abstract class StoragesControllerTest extends \Test\TestCase {
}
public function testAddOrUpdateStorageInvalidBackend() {
+ $this->service->expects($this->exactly(2))
+ ->method('createStorage')
+ ->will($this->throwException(new \InvalidArgumentException()));
$this->service->expects($this->never())
->method('addStorage');
$this->service->expects($this->never())
@@ -170,6 +214,20 @@ abstract class StoragesControllerTest extends \Test\TestCase {
}
public function testUpdateStorageNonExisting() {
+ $backend = $this->getBackendMock();
+ $backend->method('validateStorage')
+ ->willReturn(true);
+ $backend->method('isVisibleFor')
+ ->willReturn(true);
+
+ $storageConfig = new StorageConfig(255);
+ $storageConfig->setMountPoint('mount');
+ $storageConfig->setBackend($backend);
+ $storageConfig->setBackendOptions([]);
+
+ $this->service->expects($this->once())
+ ->method('createStorage')
+ ->will($this->returnValue($storageConfig));
$this->service->expects($this->once())
->method('updateStorage')
->will($this->throwException(new NotFoundException()));
@@ -206,9 +264,10 @@ abstract class StoragesControllerTest extends \Test\TestCase {
}
public function testGetStorage() {
+ $backend = $this->getBackendMock();
$storageConfig = new StorageConfig(1);
$storageConfig->setMountPoint('test');
- $storageConfig->setBackendClass('\OC\Files\Storage\SMB');
+ $storageConfig->setBackend($backend);
$storageConfig->setBackendOptions(['user' => 'test', 'password', 'password123']);
$storageConfig->setMountOptions(['priority' => false]);
diff --git a/apps/files_external/tests/controller/userstoragescontrollertest.php b/apps/files_external/tests/controller/userstoragescontrollertest.php
index f9b4c5b2681..99825f26394 100644
--- a/apps/files_external/tests/controller/userstoragescontrollertest.php
+++ b/apps/files_external/tests/controller/userstoragescontrollertest.php
@@ -24,6 +24,8 @@ use \OCA\Files_external\Controller\UserStoragesController;
use \OCA\Files_external\Service\UserStoragesService;
use \OCP\AppFramework\Http;
use \OCA\Files_external\NotFoundException;
+use \OCA\Files_External\Lib\StorageConfig;
+use \OCA\Files_External\Service\BackendService;
class UserStoragesControllerTest extends StoragesControllerTest {
@@ -44,41 +46,22 @@ class UserStoragesControllerTest extends StoragesControllerTest {
$this->getMock('\OCP\IL10N'),
$this->service
);
-
- $config = \OC::$server->getConfig();
-
- $this->oldAllowedBackends = $config->getAppValue(
- 'files_external',
- 'user_mounting_backends',
- ''
- );
- $config->setAppValue(
- 'files_external',
- 'user_mounting_backends',
- '\OC\Files\Storage\SMB'
- );
}
- public function tearDown() {
- $config = \OC::$server->getConfig();
- $config->setAppValue(
- 'files_external',
- 'user_mounting_backends',
- $this->oldAllowedBackends
- );
- parent::tearDown();
- }
+ public function testAddOrUpdateStorageDisallowedBackend() {
+ $backend = $this->getBackendMock();
+ $backend->method('isVisibleFor')
+ ->with(BackendService::VISIBILITY_PERSONAL)
+ ->willReturn(false);
- function disallowedBackendClassProvider() {
- return array(
- array('\OC\Files\Storage\Local'),
- array('\OC\Files\Storage\FTP'),
- );
- }
- /**
- * @dataProvider disallowedBackendClassProvider
- */
- public function testAddOrUpdateStorageDisallowedBackend($backendClass) {
+ $storageConfig = new StorageConfig(1);
+ $storageConfig->setMountPoint('mount');
+ $storageConfig->setBackend($backend);
+ $storageConfig->setBackendOptions([]);
+
+ $this->service->expects($this->exactly(2))
+ ->method('createStorage')
+ ->will($this->returnValue($storageConfig));
$this->service->expects($this->never())
->method('addStorage');
$this->service->expects($this->never())
@@ -86,7 +69,7 @@ class UserStoragesControllerTest extends StoragesControllerTest {
$response = $this->controller->create(
'mount',
- $backendClass,
+ '\OC\Files\Storage\SMB',
array(),
[],
[],
@@ -99,7 +82,7 @@ class UserStoragesControllerTest extends StoragesControllerTest {
$response = $this->controller->update(
1,
'mount',
- $backendClass,
+ '\OC\Files\Storage\SMB',
array(),
[],
[],
diff --git a/apps/files_external/tests/dynamicmountconfig.php b/apps/files_external/tests/dynamicmountconfig.php
deleted file mode 100644
index 48791ca89a5..00000000000
--- a/apps/files_external/tests/dynamicmountconfig.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2015, 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/>
- *
- */
-
-require_once __DIR__ . '/../../../lib/base.php';
-
-/**
- * Class Test_Mount_Config_Dummy_Backend
- */
-class Test_Mount_Config_Dummy_Backend {
- public static $checkDependencies = true;
-
- public static function checkDependencies() {
- return self::$checkDependencies;
- }
-}
-
-/**
- * Class Test_Dynamic_Mount_Config
- */
-class Test_Dynamic_Mount_Config extends \Test\TestCase {
-
- private $backup;
-
- public function testRegistration() {
-
- // second registration shall return false
- $result = OC_Mount_Config::registerBackend('Test_Mount_Config_Dummy_Backend', array(
- 'backend' => 'Test Dummy',
- 'configuration' => array(),
- 'has_dependencies' => true));
-
- $this->assertTrue($result);
- }
-
- public function testDependencyGetBackend() {
-
- // is the backend listed?
- Test_Mount_Config_Dummy_Backend::$checkDependencies = true;
- $backEnds = OC_Mount_Config::getBackends();
- $this->assertArrayHasKey('Test_Mount_Config_Dummy_Backend', $backEnds);
-
- // backend shall not be listed
- Test_Mount_Config_Dummy_Backend::$checkDependencies = false;
-
- $backEnds = OC_Mount_Config::getBackends();
- $this->assertArrayNotHasKey('Test_Mount_Config_Dummy_Backend', $backEnds);
-
- }
-
- public function testCheckDependencies() {
-
- Test_Mount_Config_Dummy_Backend::$checkDependencies = true;
- $message = OC_Mount_Config::checkDependencies();
- $this->assertEmpty($message);
-
- // backend shall not be listed
- Test_Mount_Config_Dummy_Backend::$checkDependencies = array('dummy');
-
- $message = OC_Mount_Config::checkDependencies();
- $this->assertEquals('<br /><b>Note:</b> "dummy" is not installed. Mounting of <i>Test Dummy</i> is not possible. Please ask your system administrator to install it.',
- $message);
-
- }
-
- protected function setUp() {
- parent::setUp();
-
- $this->backup = OC_Mount_Config::setUp();
-
- // register dummy backend
- $result = OC_Mount_Config::registerBackend('Test_Mount_Config_Dummy_Backend', array(
- 'backend' => 'Test Dummy',
- 'configuration' => array(),
- 'has_dependencies' => true));
-
- $this->assertTrue($result);
- }
-
- protected function tearDown()
- {
- OC_Mount_Config::setUp($this->backup);
- parent::tearDown();
- }
-}
diff --git a/apps/files_external/tests/service/globalstoragesservicetest.php b/apps/files_external/tests/service/globalstoragesservicetest.php
index ac25f58b1d1..422f3543f35 100644
--- a/apps/files_external/tests/service/globalstoragesservicetest.php
+++ b/apps/files_external/tests/service/globalstoragesservicetest.php
@@ -29,7 +29,7 @@ use \OCA\Files_external\Lib\StorageConfig;
class GlobalStoragesServiceTest extends StoragesServiceTest {
public function setUp() {
parent::setUp();
- $this->service = new GlobalStoragesService();
+ $this->service = new GlobalStoragesService($this->backendService);
}
public function tearDown() {
@@ -59,7 +59,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
return [
// all users
[
- $this->makeStorageConfig([
+ [
'mountPoint' => 'mountpoint',
'backendClass' => '\OC\Files\Storage\SMB',
'backendOptions' => [
@@ -70,11 +70,11 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
'applicableUsers' => [],
'applicableGroups' => [],
'priority' => 15,
- ]),
+ ],
],
// some users
[
- $this->makeStorageConfig([
+ [
'mountPoint' => 'mountpoint',
'backendClass' => '\OC\Files\Storage\SMB',
'backendOptions' => [
@@ -85,11 +85,11 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
'applicableUsers' => ['user1', 'user2'],
'applicableGroups' => [],
'priority' => 15,
- ]),
+ ],
],
// some groups
[
- $this->makeStorageConfig([
+ [
'mountPoint' => 'mountpoint',
'backendClass' => '\OC\Files\Storage\SMB',
'backendOptions' => [
@@ -100,11 +100,11 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
'applicableUsers' => [],
'applicableGroups' => ['group1', 'group2'],
'priority' => 15,
- ]),
+ ],
],
// both users and groups
[
- $this->makeStorageConfig([
+ [
'mountPoint' => 'mountpoint',
'backendClass' => '\OC\Files\Storage\SMB',
'backendOptions' => [
@@ -115,7 +115,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
'applicableUsers' => ['user1', 'user2'],
'applicableGroups' => ['group1', 'group2'],
'priority' => 15,
- ]),
+ ],
],
];
}
@@ -123,7 +123,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
/**
* @dataProvider storageDataProvider
*/
- public function testAddStorage($storage) {
+ public function testAddStorage($storageParams) {
+ $storage = $this->makeStorageConfig($storageParams);
$newStorage = $this->service->addStorage($storage);
$this->assertEquals(1, $newStorage->getId());
@@ -132,7 +133,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
$newStorage = $this->service->getStorage(1);
$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
- $this->assertEquals($storage->getBackendClass(), $newStorage->getBackendClass());
+ $this->assertEquals($storage->getBackend(), $newStorage->getBackend());
$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
$this->assertEquals($storage->getApplicableUsers(), $newStorage->getApplicableUsers());
$this->assertEquals($storage->getApplicableGroups(), $newStorage->getApplicableGroups());
@@ -148,7 +149,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
/**
* @dataProvider storageDataProvider
*/
- public function testUpdateStorage($updatedStorage) {
+ public function testUpdateStorage($updatedStorageParams) {
+ $updatedStorage = $this->makeStorageConfig($updatedStorageParams);
$storage = $this->makeStorageConfig([
'mountPoint' => 'mountpoint',
'backendClass' => '\OC\Files\Storage\SMB',
diff --git a/apps/files_external/tests/service/storagesservicetest.php b/apps/files_external/tests/service/storagesservicetest.php
index 36f68a83b11..99e179cc93a 100644
--- a/apps/files_external/tests/service/storagesservicetest.php
+++ b/apps/files_external/tests/service/storagesservicetest.php
@@ -24,6 +24,7 @@ use \OC\Files\Filesystem;
use \OCA\Files_external\NotFoundException;
use \OCA\Files_external\Lib\StorageConfig;
+use \OCA\Files_External\Lib\BackendService;
abstract class StoragesServiceTest extends \Test\TestCase {
@@ -32,6 +33,9 @@ abstract class StoragesServiceTest extends \Test\TestCase {
*/
protected $service;
+ /** @var BackendService */
+ protected $backendService;
+
/**
* Data directory
*
@@ -55,6 +59,25 @@ abstract class StoragesServiceTest extends \Test\TestCase {
);
\OC_Mount_Config::$skipTest = true;
+ $this->backendService =
+ $this->getMockBuilder('\OCA\Files_External\Service\BackendService')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $backends = [
+ '\OC\Files\Storage\SMB' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SMB', '\OC\Files\Storage\SMB'),
+ '\OC\Files\Storage\SFTP' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SFTP', '\OC\Files\Storage\SFTP'),
+ ];
+ $this->backendService->method('getBackend')
+ ->will($this->returnCallback(function($backendClass) use ($backends) {
+ if (isset($backends[$backendClass])) {
+ return $backends[$backendClass];
+ }
+ return null;
+ }));
+ $this->backendService->method('getBackends')
+ ->will($this->returnValue($backends));
+
\OCP\Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_create_mount,
@@ -71,6 +94,17 @@ abstract class StoragesServiceTest extends \Test\TestCase {
self::$hookCalls = array();
}
+ protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') {
+ $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->method('getStorageClass')
+ ->willReturn($storageClass);
+ $backend->method('getClass')
+ ->willReturn($storageClass);
+ return $backend;
+ }
+
/**
* Creates a StorageConfig instance based on array data
*
@@ -84,7 +118,12 @@ abstract class StoragesServiceTest extends \Test\TestCase {
$storage->setId($data['id']);
}
$storage->setMountPoint($data['mountPoint']);
- $storage->setBackendClass($data['backendClass']);
+ if (!isset($data['backend'])) {
+ // data providers are run before $this->backendService is initialised
+ // so $data['backend'] can be specified directly
+ $data['backend'] = $this->backendService->getBackend($data['backendClass']);
+ }
+ $storage->setBackend($data['backend']);
$storage->setBackendOptions($data['backendOptions']);
if (isset($data['applicableUsers'])) {
$storage->setApplicableUsers($data['applicableUsers']);
@@ -106,16 +145,18 @@ abstract class StoragesServiceTest extends \Test\TestCase {
* @expectedException \OCA\Files_external\NotFoundException
*/
public function testNonExistingStorage() {
+ $backend = $this->backendService->getBackend('\OC\Files\Storage\SMB');
$storage = new StorageConfig(255);
$storage->setMountPoint('mountpoint');
- $storage->setBackendClass('\OC\Files\Storage\SMB');
+ $storage->setBackend($backend);
$this->service->updateStorage($storage);
}
public function testDeleteStorage() {
+ $backend = $this->backendService->getBackend('\OC\Files\Storage\SMB');
$storage = new StorageConfig(255);
$storage->setMountPoint('mountpoint');
- $storage->setBackendClass('\OC\Files\Storage\SMB');
+ $storage->setBackend($backend);
$storage->setBackendOptions(['password' => 'testPassword']);
$newStorage = $this->service->addStorage($storage);
diff --git a/apps/files_external/tests/service/userstoragesservicetest.php b/apps/files_external/tests/service/userstoragesservicetest.php
index ab102741ee2..98a9993918a 100644
--- a/apps/files_external/tests/service/userstoragesservicetest.php
+++ b/apps/files_external/tests/service/userstoragesservicetest.php
@@ -40,7 +40,7 @@ class UserStoragesServiceTest extends StoragesServiceTest {
->method('getUser')
->will($this->returnValue($this->user));
- $this->service = new UserStoragesService($userSession);
+ $this->service = new UserStoragesService($this->backendService, $userSession);
// create home folder
mkdir($this->dataDir . '/' . $this->userId . '/');
@@ -76,7 +76,7 @@ class UserStoragesServiceTest extends StoragesServiceTest {
$newStorage = $this->service->getStorage(1);
$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
- $this->assertEquals($storage->getBackendClass(), $newStorage->getBackendClass());
+ $this->assertEquals($storage->getBackend(), $newStorage->getBackend());
$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
$this->assertEquals(1, $newStorage->getId());
$this->assertEquals(0, $newStorage->getStatus());
diff --git a/apps/files_external/tests/storageconfigtest.php b/apps/files_external/tests/storageconfigtest.php
index c30a4935ce1..69edb36e707 100644
--- a/apps/files_external/tests/storageconfigtest.php
+++ b/apps/files_external/tests/storageconfigtest.php
@@ -26,9 +26,15 @@ use \OCA\Files_external\Lib\StorageConfig;
class StorageConfigTest extends \Test\TestCase {
public function testJsonSerialization() {
+ $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->method('getClass')
+ ->willReturn('\OC\Files\Storage\SMB');
+
$storageConfig = new StorageConfig(1);
$storageConfig->setMountPoint('test');
- $storageConfig->setBackendClass('\OC\Files\Storage\SMB');
+ $storageConfig->setBackend($backend);
$storageConfig->setBackendOptions(['user' => 'test', 'password' => 'password123']);
$storageConfig->setPriority(128);
$storageConfig->setApplicableUsers(['user1', 'user2']);