Skip to content

Commit

Permalink
Introduce BackendService for managing external storage backends
Browse files Browse the repository at this point in the history
Backends are registered to the BackendService through new data
structures:

BackendConfig specifies the basic information for a backend: class,
human-readable name, visibility to personal/admin, initial priority. It
takes an array of BackendParameter's to specifiy the parameters

BackendParameter 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).

When a BackendConfig has checkDependencies() called on it, it will
return a (possibly empty) array of BackendDependency's that specify a
dependency of the backend. If an empty array is returned it means there
are no unhandled dependencies, so the backend can be used.

Storages in the StoragesController now get their parameters validated
server-side (fixes a TODO).
  • Loading branch information
Robin McCorkell committed May 11, 2015
1 parent 90d8e4b commit f2e4a22
Show file tree
Hide file tree
Showing 12 changed files with 1,007 additions and 430 deletions.
173 changes: 3 additions & 170 deletions apps/files_external/appinfo/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
8 changes: 6 additions & 2 deletions apps/files_external/controller/globalstoragescontroller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
);
}

Expand Down
24 changes: 19 additions & 5 deletions apps/files_external/controller/storagescontroller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -52,23 +53,29 @@ abstract class StoragesController extends Controller {
*/
protected $service;

/** @var BackendService */
protected $backendService;

/**
* Creates a new storages controller.
*
* @param string $AppName application name
* @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;
}

/**
Expand All @@ -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(
Expand All @@ -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;
}
Expand Down
17 changes: 11 additions & 6 deletions apps/files_external/controller/userstoragescontroller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
);
}

Expand All @@ -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
);
Expand Down
Loading

0 comments on commit f2e4a22

Please sign in to comment.