diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 8fa0d0b52236..165953e210f2 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -64,179 +64,12 @@ "name" => $l->t('External storage') ]); +// Teach OC_Mount_Config about the AppFramework +\OC_Mount_Config::initApp($app->getContainer()); + // 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'); -OC_Mount_Config::registerBackend('\OC\Files\Storage\Local', [ - 'backend' => (string)$l->t('Local'), - 'priority' => 150, - 'configuration' => [ - 'datadir' => (string)$l->t('Location') - ], -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\AmazonS3', [ - 'backend' => (string)$l->t('Amazon S3'), - 'priority' => 100, - 'configuration' => [ - 'key' => (string)$l->t('Key'), - 'secret' => '*'.$l->t('Secret'), - 'bucket' => (string)$l->t('Bucket'), - ], - 'has_dependencies' => true, -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\AmazonS3', [ - 'backend' => (string)$l->t('Amazon S3 and compliant'), - 'priority' => 100, - 'configuration' => [ - 'key' => (string)$l->t('Access Key'), - 'secret' => '*'.$l->t('Secret Key'), - 'bucket' => (string)$l->t('Bucket'), - 'hostname' => '&'.$l->t('Hostname'), - 'port' => '&'.$l->t('Port'), - 'region' => '&'.$l->t('Region'), - 'use_ssl' => '!'.$l->t('Enable SSL'), - 'use_path_style' => '!'.$l->t('Enable Path Style') - ], - 'has_dependencies' => true, -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\Dropbox', [ - 'backend' => 'Dropbox', - 'priority' => 100, - 'configuration' => [ - 'configured' => '#configured', - 'app_key' => (string)$l->t('App key'), - 'app_secret' => '*'.$l->t('App secret'), - 'token' => '#token', - 'token_secret' => '#token_secret' - ], - 'custom' => 'dropbox', - 'has_dependencies' => true, -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\FTP', [ - 'backend' => 'FTP', - 'priority' => 100, - 'configuration' => [ - 'host' => (string)$l->t('Host'), - 'user' => (string)$l->t('Username'), - 'password' => '*'.$l->t('Password'), - 'root' => '&'.$l->t('Remote subfolder'), - 'secure' => '!'.$l->t('Secure ftps://') - ], - 'has_dependencies' => true, -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\Google', [ - 'backend' => 'Google Drive', - 'priority' => 100, - 'configuration' => [ - 'configured' => '#configured', - 'client_id' => (string)$l->t('Client ID'), - 'client_secret' => '*'.$l->t('Client secret'), - 'token' => '#token', - ], - 'custom' => 'google', - 'has_dependencies' => true, -]); - - -OC_Mount_Config::registerBackend('\OC\Files\Storage\Swift', [ - 'backend' => (string)$l->t('OpenStack Object Storage'), - 'priority' => 100, - 'configuration' => [ - 'user' => (string)$l->t('Username'), - 'bucket' => (string)$l->t('Bucket'), - 'region' => '&'.$l->t('Region (optional for OpenStack Object Storage)'), - 'key' => '&*'.$l->t('API Key (required for Rackspace Cloud Files)'), - 'tenant' => '&'.$l->t('Tenantname (required for OpenStack Object Storage)'), - 'password' => '&*'.$l->t('Password (required for OpenStack Object Storage)'), - 'service_name' => '&'.$l->t('Service Name (required for OpenStack Object Storage)'), - 'url' => '&'.$l->t('URL of identity endpoint (required for OpenStack Object Storage)'), - 'timeout' => '&'.$l->t('Timeout of HTTP requests in seconds'), - ], - 'has_dependencies' => true, -]); - - -if (!OC_Util::runningOnWindows()) { - OC_Mount_Config::registerBackend('\OC\Files\Storage\SMB', [ - 'backend' => 'SMB / CIFS', - 'priority' => 100, - 'configuration' => [ - 'host' => (string)$l->t('Host'), - 'user' => (string)$l->t('Username'), - 'password' => '*'.$l->t('Password'), - 'share' => (string)$l->t('Share'), - 'root' => '&'.$l->t('Remote subfolder'), - ], - 'has_dependencies' => true, - ]); - - OC_Mount_Config::registerBackend('\OC\Files\Storage\SMB_OC', [ - 'backend' => (string)$l->t('SMB / CIFS using OC login'), - 'priority' => 90, - 'configuration' => [ - 'host' => (string)$l->t('Host'), - 'username_as_share' => '!'.$l->t('Username as share'), - 'share' => '&'.$l->t('Share'), - 'root' => '&'.$l->t('Remote subfolder'), - ], - 'has_dependencies' => true, - ]); -} - -OC_Mount_Config::registerBackend('\OC\Files\Storage\DAV', [ - 'backend' => 'WebDAV', - 'priority' => 100, - 'configuration' => [ - 'host' => (string)$l->t('URL'), - 'user' => (string)$l->t('Username'), - 'password' => '*'.$l->t('Password'), - 'root' => '&'.$l->t('Remote subfolder'), - 'secure' => '!'.$l->t('Secure https://'), - ], - 'has_dependencies' => true, -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\OwnCloud', [ - 'backend' => 'ownCloud', - 'priority' => 100, - 'configuration' => [ - 'host' => (string)$l->t('URL'), - 'user' => (string)$l->t('Username'), - 'password' => '*'.$l->t('Password'), - 'root' => '&'.$l->t('Remote subfolder'), - 'secure' => '!'.$l->t('Secure https://'), - ], -]); - - -OC_Mount_Config::registerBackend('\OC\Files\Storage\SFTP', [ - 'backend' => 'SFTP', - 'priority' => 100, - 'configuration' => [ - 'host' => (string)$l->t('Host'), - 'user' => (string)$l->t('Username'), - 'password' => '*'.$l->t('Password'), - 'root' => '&'.$l->t('Remote subfolder'), - ], -]); - -OC_Mount_Config::registerBackend('\OC\Files\Storage\SFTP_Key', [ - 'backend' => 'SFTP with secret key login', - 'priority' => 100, - 'configuration' => array( - 'host' => (string)$l->t('Host'), - 'user' => (string)$l->t('Username'), - 'public_key' => (string)$l->t('Public key'), - 'private_key' => '#private_key', - 'root' => '&'.$l->t('Remote subfolder')), - 'custom' => 'sftp_key', - ] -); $mountProvider = new \OCA\Files_External\Config\ConfigAdapter(); \OC::$server->getMountProviderCollection()->registerProvider($mountProvider); diff --git a/apps/files_external/controller/globalstoragescontroller.php b/apps/files_external/controller/globalstoragescontroller.php index 33f870d48e32..63992fd2e535 100644 --- a/apps/files_external/controller/globalstoragescontroller.php +++ b/apps/files_external/controller/globalstoragescontroller.php @@ -30,6 +30,7 @@ use \OCP\AppFramework\Controller; use \OCP\AppFramework\Http; use \OCA\Files_external\Service\GlobalStoragesService; +use \OCA\Files_External\Service\BackendService; use \OCA\Files_external\NotFoundException; use \OCA\Files_external\Lib\StorageConfig; @@ -44,18 +45,21 @@ class GlobalStoragesController extends StoragesController { * @param IRequest $request request object * @param IL10N $l10n l10n service * @param GlobalStoragesService $globalStoragesService storage service + * @param BackendService $backendService */ public function __construct( $AppName, IRequest $request, IL10N $l10n, - GlobalStoragesService $globalStoragesService + GlobalStoragesService $globalStoragesService, + BackendService $backendService ) { parent::__construct( $AppName, $request, $l10n, - $globalStoragesService + $globalStoragesService, + $backendService ); } diff --git a/apps/files_external/controller/storagescontroller.php b/apps/files_external/controller/storagescontroller.php index c09ceacc7d73..f5d8ff241e4c 100644 --- a/apps/files_external/controller/storagescontroller.php +++ b/apps/files_external/controller/storagescontroller.php @@ -30,6 +30,7 @@ use \OCP\AppFramework\Controller; use \OCP\AppFramework\Http; use \OCA\Files_external\Service\StoragesService; +use \OCA\Files_External\Service\BackendService; use \OCA\Files_external\NotFoundException; use \OCA\Files_external\Lib\StorageConfig; @@ -52,6 +53,9 @@ abstract class StoragesController extends Controller { */ protected $service; + /** @var BackendService */ + protected $backendService; + /** * Creates a new storages controller. * @@ -59,16 +63,19 @@ abstract class StoragesController extends Controller { * @param IRequest $request request object * @param IL10N $l10n l10n service * @param StoragesService $storagesService storage service + * @param BackendService $backendService */ public function __construct( $AppName, IRequest $request, IL10N $l10n, - StoragesService $storagesService + StoragesService $storagesService, + BackendService $backendService ) { parent::__construct($AppName, $request); $this->l10n = $l10n; $this->service = $storagesService; + $this->backendService = $backendService; } /** @@ -89,10 +96,8 @@ protected function validate(StorageConfig $storage) { ); } - // TODO: validate that other attrs are set - - $backends = \OC_Mount_Config::getBackends(); - if (!isset($backends[$storage->getBackendClass()])) { + $backend = $this->backendService->getBackend($storage->getBackendClass()); + if (!$backend || $backend->checkDependencies()) { // invalid backend return new DataResponse( array( @@ -101,6 +106,15 @@ protected function validate(StorageConfig $storage) { 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 + ); + } return null; } diff --git a/apps/files_external/controller/userstoragescontroller.php b/apps/files_external/controller/userstoragescontroller.php index f5d22e5caa69..c1e31e4bffe3 100644 --- a/apps/files_external/controller/userstoragescontroller.php +++ b/apps/files_external/controller/userstoragescontroller.php @@ -30,8 +30,10 @@ 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\BackendConfig; /** * User storages controller @@ -44,18 +46,21 @@ class UserStoragesController extends StoragesController { * @param IRequest $request request object * @param IL10N $l10n l10n service * @param UserStoragesService $userStoragesService storage service + * @param BackendService $backendService */ public function __construct( $AppName, IRequest $request, IL10N $l10n, - UserStoragesService $userStoragesService + UserStoragesService $userStoragesService, + BackendService $backendService ) { parent::__construct( $AppName, $request, $l10n, - $userStoragesService + $userStoragesService, + $backendService ); } @@ -69,17 +74,17 @@ public function __construct( 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()])) { + $backend = $this->backendService->getBackend($storage->getBackendClass()); + if (!$backend->isVisibleFor(BackendConfig::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"', array($storage->getBackendClass())) ), Http::STATUS_UNPROCESSABLE_ENTITY ); diff --git a/apps/files_external/lib/backendconfig.php b/apps/files_external/lib/backendconfig.php new file mode 100644 index 000000000000..a0948c32ccb3 --- /dev/null +++ b/apps/files_external/lib/backendconfig.php @@ -0,0 +1,260 @@ + + * + * @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 + * + */ + +namespace OCA\Files_External\Lib; + +use \OCA\Files_External\Lib\BackendParameter; +use \OCA\Files_External\Lib\BackendDependency; + +/** + * External storage backend configuration + */ +class BackendConfig implements \JsonSerializable { + + /** Visibility constants */ + const VISIBILITY_NONE = 0; + const VISIBILITY_PERSONAL = 1; + const VISIBILITY_ADMIN = 2; + //const VISIBILITY_ALIENS = 4; + + const VISIBILITY_DEFAULT = 3; // PERSONAL | ADMIN + + /** Initial priority constants */ + const PRIORITY_DEFAULT = 100; + + /** @var string backend class */ + private $class; + + /** @var string human-readable backend name */ + private $text; + + /** @var BackendParameter[] parameters for backend */ + private $parameters = []; + + /** @var int initial priority */ + private $priority = self::PRIORITY_DEFAULT; + + /** @var bool has dependencies */ + private $hasDependencies = false; + + /** @var string|null custom JS */ + private $customJs = null; + + /** @var int visibility, see self::VISIBILITY_* constants */ + private $visibility = self::VISIBILITY_DEFAULT; + + /** + * @param string $class Backend class + * @param string $text Human-readable name + * @param BackendParameter[] $parameters + */ + public function __construct($class, $text, $parameters) { + $this->class = $class; + $this->text = $text; + $this->parameters = $parameters; + } + + /** + * @return string + */ + public function getClass() { + return $this->class; + } + + /** + * @return string + */ + public function getText() { + return $this->text; + } + + /** + * @return BackendParameter[] + */ + public function getParameters() { + return $this->parameters; + } + + /** + * @return int + */ + public function getPriority() { + return $this->priority; + } + + /** + * @param int $priority + * @return self + */ + public function setPriority($priority) { + $this->priority = $priority; + return $this; + } + + /** + * @return bool + */ + public function hasDependencies() { + return $this->hasDependencies; + } + + /** + * @param bool $hasDependencies + * @return self + */ + public function setHasDependencies($hasDependencies) { + $this->hasDependencies = $hasDependencies; + 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; + } + + /** + * @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; + return $this; + } + + /** + * Serialize into JSON for client-side JS + * + * @return array + */ + public function jsonSerialize() { + $configuration = []; + foreach ($this->getParameters() as $parameter) { + $configuration[$parameter->getName()] = $parameter; + } + + $data = [ + 'backend' => $this->getText(), + 'priority' => $this->getPriority(), + 'configuration' => $configuration, + ]; + if (isset($this->customJs)) { + $data['custom'] = $this->customJs; + } + return $data; + } + + /** + * Check if backend is valid for use + * + * @return BackendDependency[] Unsatisfied dependencies + */ + public function checkDependencies() { + $ret = []; + + if ($this->hasDependencies()) { + $class = $this->getClass(); + $result = $class::checkDependencies(); + if ($result !== true) { + if (!is_array($result)) { + $result = [$result]; + } + foreach ($result as $key => $value) { + if (!($value instanceof BackendDependency)) { + $module = null; + $message = null; + if (is_numeric($key)) { + $module = $value; + } else { + $module = $key; + $message = $value; + } + $value = new BackendDependency($module, $this); + $value->setMessage($message); + } + $ret[] = $value; + } + } + } + + return $ret; + } + + /** + * Check if parameters are satisfied in a StorageConfig + * + * @param StorageConfig $storage + * @return bool + */ + public function validateStorage(StorageConfig $storage) { + $options = $storage->getBackendOptions(); + foreach ($this->parameters as $parameter) { + if ($parameter->getFlags() & BackendParameter::FLAG_OPTIONAL) { + continue; + } + switch ($parameter->getType()) { + case BackendParameter::VALUE_BOOLEAN: + if (!isset($options[$parameter->getName()]) || + !is_bool($options[$parameter->getName()]) + ) { + return false; + } + break; + default: + if (empty($options[$parameter->getName()])) { + return false; + } + break; + } + } + return true; + } +} diff --git a/apps/files_external/lib/backenddependency.php b/apps/files_external/lib/backenddependency.php new file mode 100644 index 000000000000..db3bd217cab4 --- /dev/null +++ b/apps/files_external/lib/backenddependency.php @@ -0,0 +1,77 @@ + + * + * @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 + * + */ + +namespace OCA\Files_External\Lib; + +use \OCA\Files_External\Lib\BackendConfig; + +/** + * External storage backend dependency + */ +class BackendDependency { + + /** @var string */ + private $dependency; + + /** @var BackendConfig Backend to which the dependency applies */ + private $backend; + + /** @var string|null Custom message */ + private $message = null; + + /** + * @param string $dependency + * @param BackendConfig $backend + */ + public function __construct($dependency, BackendConfig $backend) { + $this->dependency = $dependency; + $this->backend = $backend; + } + + /** + * @return string + */ + public function getDependency() { + return $this->dependency; + } + + /** + * @return BackendConfig + */ + public function getBackend() { + return $this->backend; + } + + /** + * @return string|null + */ + public function getMessage() { + return $this->message; + } + + /** + * @param string|null $message + * @return self + */ + public function setMessage($message) { + $this->message = $message; + } +} diff --git a/apps/files_external/lib/backendparameter.php b/apps/files_external/lib/backendparameter.php new file mode 100644 index 000000000000..f5bd514c1df9 --- /dev/null +++ b/apps/files_external/lib/backendparameter.php @@ -0,0 +1,154 @@ + + * + * @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 + * + */ + +namespace OCA\Files_External\Lib; + +/** + * External storage backend parameter + */ +class BackendParameter 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(); + } +} diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 40e9a75790f7..7f648c6fbd97 100644 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -31,6 +31,9 @@ * */ +use \OCP\AppFramework\IAppContainer; +use \OCA\Files_External\Lib\BackendConfig; + /** * Class to configure mount.json globally and for users */ @@ -49,71 +52,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 - * - * @return array of previously registered backends - */ - 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 + * Teach OC_Mount_Config about the AppFramework * - * @return array + * @param IAppContainer $appContainer */ - 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 @@ -149,14 +100,14 @@ public static function initMountPointsHook($data) { /** * 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(); @@ -164,18 +115,20 @@ public static function getAbsoluteMountPoints($user) { // 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; } } @@ -188,10 +141,11 @@ public static function getAbsoluteMountPoints($user) { 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 @@ -199,7 +153,7 @@ public static function getAbsoluteMountPoints($user) { || ($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; } } @@ -213,10 +167,11 @@ public static function getAbsoluteMountPoints($user) { 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 @@ -225,7 +180,7 @@ public static function getAbsoluteMountPoints($user) { || ($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; } } @@ -241,10 +196,11 @@ public static function getAbsoluteMountPoints($user) { 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 @@ -253,7 +209,7 @@ public static function getAbsoluteMountPoints($user) { || ($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; } } @@ -261,19 +217,18 @@ public static function getAbsoluteMountPoints($user) { } } - $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(BackendConfig::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; } } @@ -302,43 +257,6 @@ private static function setUserVars($user, $input) { 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() @@ -347,7 +265,7 @@ public static function getPersonalBackends() { */ 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) { @@ -356,9 +274,10 @@ public static function getSystemMountPoints() { 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); @@ -366,7 +285,7 @@ public static function getSystemMountPoints() { $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()) @@ -399,16 +318,17 @@ public static function getSystemMountPoints() { 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)) @@ -445,7 +365,7 @@ public static function getSystemMountPoints() { */ 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])) { @@ -454,12 +374,13 @@ public static function getPersonalMountPoints() { 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'])) { @@ -525,7 +446,7 @@ public static function addMountPoint($mountPoint, $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 === '/') { @@ -533,15 +454,15 @@ public static function addMountPoint($mountPoint, 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, '/'); @@ -568,13 +489,8 @@ public static function addMountPoint($mountPoint, // 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); @@ -711,74 +627,35 @@ public static function writeData($user, $data) { } /** - * 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 .= '
' . $l->t('Note: ') . $backend['message']; + $message = ''; + $dependencyGroups = []; + + foreach ($backends as $backend) { + foreach ($backend->checkDependencies() as $dependency) { + if ($message = $dependency->getMessage()) { + $message .= '
' . $l->t('Note: ') . $message; } else { - $dependencyGroup[] = $backend; + $dependencyGroups[$dependency->getDependency()][] = $dependency; } } + } - $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 .= '' . $dependencyGroup[$i] . ''; - } - $dependencyMessage .= '
' . OC_Mount_Config::getSingleDependencyMessage($l, $module, $backends); - } + foreach ($dependencyGroups as $module => $dependencies) { + $backends = implode(', ', array_map(function($dependency) { + return '' . $dependency->getBackend()->getText() . ''; + }, $dependencies)); + $message .= '
' . OC_Mount_Config::getSingleDependencyMessage($l, $module, $backends); } - return $dependencyMessage; + + return $message; } /** diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index b2ab32411f99..593a973259d8 100644 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -23,9 +23,12 @@ * */ +$app = new \OCA\Files_external\Appinfo\Application(); +$appContainer = $app->getContainer(); +$backendService = $appContainer->query('\OCA\Files_External\Service\BackendService'); + OCP\Util::addScript('files_external', 'settings'); OCP\Util::addStyle('files_external', 'settings'); -$backends = OC_Mount_Config::getPersonalBackends(); $mounts = OC_Mount_Config::getPersonalMountPoints(); $hasId = true; @@ -38,10 +41,10 @@ } if (!$hasId) { - $service = new \OCA\Files_external\Service\UserStoragesService(\OC::$server->getUserSession()); + $userStoragesService = $appContainer->query('\OCA\Files_external\Service\UserStoragesService'); // this will trigger the new storage code which will automatically // generate storage config ids - $service->getAllStorages(); + $userStoragesService->getAllStorages(); // re-read updated config $mounts = OC_Mount_Config::getPersonalMountPoints(); // TODO: use the new storage config format in the template @@ -51,6 +54,6 @@ $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('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); +$tmpl->assign('backends', $backendService->getUserBackends()); return $tmpl->fetchPage(); diff --git a/apps/files_external/service/backendservice.php b/apps/files_external/service/backendservice.php new file mode 100644 index 000000000000..5da3be45e2c5 --- /dev/null +++ b/apps/files_external/service/backendservice.php @@ -0,0 +1,340 @@ + + * + * @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 + * + */ + +namespace OCA\Files_External\Service; + +use \OCP\IConfig; +use \OCP\IL10N; + +use \OCA\Files_External\Lib\BackendConfig; +use \OCA\Files_External\Lib\BackendParameter as Param; + +/** + * Service class to manage backend definitions + */ +class BackendService { + + /** @var IConfig */ + protected $config; + + /** @var IL10N */ + protected $l10n; + + /** @var bool */ + private $userMountingAllowed = true; + + /** @var string[] */ + private $userMountingBackends = []; + + /** @var BackendConfig[] */ + private $backends = []; + + /** @var bool If backends are sorted */ + private $backendsSorted = false; + + /** + * @param IConfig $config + * @param IL10N $l10n + */ + public function __construct( + IConfig $config, + IL10N $l10n + ) { + $this->config = $config; + $this->l10n = $l10n; + + // Load config values + if ($this->config->getAppValue('files_external', 'allow_user_mounting', 'yes') !== 'yes') { + $this->userMountingAllowed = false; + } + $this->userMountingBackends = explode(',', + $this->config->getAppValue('files_external', 'user_mounting_backends', '') + ); + + $this->loadBackends(); + } + + /** + * Register a backend + * + * @param BackendConfig $backend + */ + public function registerBackend(BackendConfig $backend) { + if (! $this->isAllowedUserBackend($backend)) { + $backend->setVisibility(BackendConfig::VISIBILITY_ADMIN); + } + $this->backends[$backend->getClass()] = $backend; + $this->backendsSorted = false; + } + + /** + * Get all backends + * + * @return BackendConfig[] + */ + public function getBackends() { + if (!$this->backendsSorted) { + uasort($this->backends, function($a, $b) { + return strcasecmp($a->getText(), $b->getText()); + }); + $this->backendsSorted = true; + } + return $this->backends; + } + + /** + * Get all available backends + * + * @return BackendConfig[] + */ + public function getAvailableBackends() { + return array_filter($this->getBackends(), function($backend) { + return empty($backend->checkDependencies()); + }); + } + + /** + * Get user-allowed backends only + * + * @return BackendConfig[] + */ + public function getUserBackends() { + return array_filter($this->getAvailableBackends(), function($backend) { + return $backend->isVisibleFor(BackendConfig::VISIBILITY_PERSONAL); + }); + } + + /** + * @param string $class Backend class name + * @return BackendConfig|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 BackendConfig $backend + * @return bool + */ + protected function isAllowedUserBackend(BackendConfig $backend) { + if ($this->userMountingAllowed && + in_array($backend->getClass(), $this->userMountingBackends) + ) { + return true; + } + return false; + } + + /** + * Load backends + */ + protected function loadBackends() { + $l = $this->l10n; + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\Local', $l->t('Local'), [ + (new Param('datadir', $l->t('Location'))), + ])) + ->setVisibility(BackendConfig::VISIBILITY_ADMIN) + ->setPriority(BackendConfig::PRIORITY_DEFAULT + 50) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\AmazonS3', $l->t('Amazon S3'), [ + (new Param('key', $l->t('Access Key'))), + (new Param('secret', $l->t('Secret Key'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('bucket', $l->t('Bucket'))), + (new Param('hostname', $l->t('Hostname'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('port', $l->t('Port'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('region', $l->t('Region'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('use_ssl', $l->t('Enable SSL'))) + ->setType(Param::VALUE_BOOLEAN), + (new Param('use_path_style', $l->t('Enable Path Style'))) + ->setType(Param::VALUE_BOOLEAN), + ])) + ->setHasDependencies(true) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\Dropbox', $l->t('Dropbox'), [ + (new Param('configured', 'configured')) + ->setType(Param::VALUE_HIDDEN), + (new Param('app_key', $l->t('App key'))), + (new Param('app_secret', $l->t('App secret'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('token', 'token')) + ->setType(Param::VALUE_HIDDEN), + (new Param('token_secret', 'token_secret')) + ->setType(Param::VALUE_HIDDEN), + ])) + ->setHasDependencies(true) + ->setCustomJs('dropbox') + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\FTP', $l->t('FTP'), [ + (new Param('host', $l->t('Host'))), + (new Param('user', $l->t('Username'))), + (new Param('password', $l->t('Password'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('root', $l->t('Remote subfolder'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('secure', $l->t('Secure ftps://'))) + ->setType(Param::VALUE_BOOLEAN), + ])) + ->setHasDependencies(true) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\Google', $l->t('Google Drive'), [ + (new Param('configured', 'configured')) + ->setType(Param::VALUE_HIDDEN), + (new Param('client_id', $l->t('Client ID'))), + (new Param('client_secret', $l->t('Client secret'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('token', 'token')) + ->setType(Param::VALUE_HIDDEN), + ])) + ->setHasDependencies(true) + ->setCustomJs('google') + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\Swift', $l->t('OpenStack Object Storage'), [ + (new Param('user', $l->t('Username'))), + (new Param('bucket', $l->t('Bucket'))), + (new Param('region', $l->t('Region (optional for OpenStack Object Storage)'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('key', $l->t('API Key (required for Rackspace Cloud Files)'))) + ->setType(Param::VALUE_PASSWORD) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('tenant', $l->t('Tenantname (required for OpenStack Object Storage)'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('password', $l->t('Password (required for OpenStack Object Storage)'))) + ->setType(Param::VALUE_PASSWORD) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('service_name', $l->t('Service Name (required for OpenStack Object Storage)'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('url', $l->t('URL of identity endpoint (required for OpenStack Object Storage)'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('timeout', $l->t('Timeout of HTTP requests in seconds'))) + ->setFlag(Param::FLAG_OPTIONAL), + ])) + ->setHasDependencies(true) + ); + + if (!\OC_Util::runningOnWindows()) { + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\SMB', $l->t('SMB / CIFS'), [ + (new Param('host', $l->t('Host'))), + (new Param('user', $l->t('Username'))), + (new Param('password', $l->t('Password'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('share', $l->t('Share'))), + (new Param('root', $l->t('Remote subfolder'))) + ->setFlag(Param::FLAG_OPTIONAL), + ])) + ->setHasDependencies(true) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\SMB_OC', $l->t(' SMB / CIFS using OC login'), [ + (new Param('host', $l->t('Host'))), + (new Param('username_as_share', $l->t('Username as share'))) + ->setType(Param::VALUE_BOOLEAN), + (new Param('share', $l->t('Share'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('root', $l->t('Remote subfolder'))) + ->setFlag(Param::FLAG_OPTIONAL), + ])) + ->setHasDependencies(true) + ->setPriority(BackendConfig::PRIORITY_DEFAULT - 10) + ); + } + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\DAV', $l->t('WebDAV'), [ + (new Param('host', $l->t('URL'))), + (new Param('user', $l->t('Username'))), + (new Param('password', $l->t('Password'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('root', $l->t('Remote subfolder'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('secure', $l->t('Secure https://'))) + ->setType(Param::VALUE_BOOLEAN), + ])) + ->setHasDependencies(true) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\OwnCloud', $l->t('ownCloud'), [ + (new Param('host', $l->t('URL'))), + (new Param('user', $l->t('Username'))), + (new Param('password', $l->t('Password'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('root', $l->t('Remote subfolder'))) + ->setFlag(Param::FLAG_OPTIONAL), + (new Param('secure', $l->t('Secure https://'))) + ->setType(Param::VALUE_BOOLEAN), + ])) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\SFTP', $l->t('SFTP'), [ + (new Param('host', $l->t('Host'))), + (new Param('user', $l->t('Username'))), + (new Param('password', $l->t('Password'))) + ->setType(Param::VALUE_PASSWORD), + (new Param('root', $l->t('Root'))) + ->setFlag(Param::FLAG_OPTIONAL), + ])) + ); + + $this->registerBackend( + (new BackendConfig('\OC\Files\Storage\SFTP_Key', $l->t('SFTP with secret key login'), [ + (new Param('host', $l->t('Host'))), + (new Param('user', $l->t('Username'))), + (new Param('public_key', $l->t('Public key'))), + (new Param('private_key', 'private_key')) + ->setType(Param::VALUE_HIDDEN), + (new Param('root', $l->t('Remote subfolder'))) + ->setFlag(Param::FLAG_OPTIONAL), + ])) + ->setCustomJs('sftp_key') + ); + } +} diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index daf205d3d578..f4e1bca38082 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -27,26 +27,16 @@ OC_Util::checkAdminUser(); +$app = new \OCA\Files_external\Appinfo\Application(); +$appContainer = $app->getContainer(); +$backendService = $appContainer->query('\OCA\Files_External\Service\BackendService'); + 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) { @@ -58,10 +48,10 @@ } if (!$hasId) { - $service = new \OCA\Files_external\Service\GlobalStoragesService(); + $globalStoragesService = $appContainer->query('\OCA\Files_external\Service\GlobalStoragesService'); // this will trigger the new storage code which will automatically // generate storage config ids - $service->getAllStorages(); + $globalStoragesService->getAllStorages(); // re-read updated config $mounts = OC_Mount_Config::getSystemMountPoints(); // TODO: use the new storage config format in the template @@ -71,8 +61,8 @@ $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('backends', $backendService->getAvailableBackends()); +$tmpl->assign('personal_backends', $backendService->getUserBackends()); +$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 b886c2e1b1b2..4f01c6888cc4 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -1,3 +1,7 @@ +

t('External Storage')); ?>

'')) print_unescaped(''.$_['dependencies'].''); ?> @@ -16,6 +20,12 @@ array('id' => ''))); ?> + data-id=""> @@ -25,59 +35,69 @@ data-mountpoint="" placeholder="t('Folder name')); ?>" /> - + - + getText()); ?> - - $value): ?> - - - + + getParameters() as $parameter): ?> + getName()])) { + $value = $mount['options'][$parameter->getName()]; + } + $placeholder = $parameter->getText(); + $is_optional = $parameter->isFlagSet(BackendParameter::FLAG_OPTIONAL); + + switch ($parameter->getType()) { + case BackendParameter::VALUE_PASSWORD: ?> class="optional" - data-parameter="" + data-parameter="getName()); ?>" value="" - placeholder="" /> - + placeholder="" /> + - + /> + - + class="optional" - data-parameter="" + data-parameter="getName()); ?>" value="" placeholder="" /> - - + - - - + getCustomJs(); + if (isset($customJs)) { + \OCP\Util::addScript('files_external', $customJs); + } + ?> @@ -123,9 +143,9 @@ class="svg action"

class="hidden"> t('Allow users to mount the following external storage')); ?>
- $backend): ?> - /> -
+ + isVisibleFor(BackendConfig::VISIBILITY_PERSONAL)) print_unescaped(' checked="checked"'); ?> /> +