diff options
author | Robin McCorkell <rmccorkell@owncloud.com> | 2015-08-11 18:45:07 +0100 |
---|---|---|
committer | Robin McCorkell <rmccorkell@owncloud.com> | 2015-08-19 10:05:11 +0100 |
commit | 37beb58c6f395523d8e2934870c5f52a8c6f6df0 (patch) | |
tree | b14325a790ddaf7236c3f8c1939ce9ef10df58bb /apps/files_external | |
parent | 74237a9c44192fb98944ea7f3c14fa6f22c0814b (diff) | |
download | nextcloud-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')
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']); |