Merge pull request #15914 from owncloud/ext-backend-register
Introduce BackendService for managing external storage backends
This commit is contained in:
commit
a9bb6be019
55 changed files with 4257 additions and 2205 deletions
|
@ -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,12 @@ OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php';
|
|||
|
||||
require_once __DIR__ . '/../3rdparty/autoload.php';
|
||||
|
||||
// register Application object singleton
|
||||
\OC_Mount_Config::$app = new \OCA\Files_external\Appinfo\Application();
|
||||
$appContainer = \OC_Mount_Config::$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');
|
||||
|
@ -74,6 +77,10 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\Local', [
|
|||
'datadir' => (string)$l->t('Location')
|
||||
],
|
||||
]);
|
||||
// Local must only be visible to the admin
|
||||
$appContainer->query('OCA\Files_External\Service\BackendService')
|
||||
->getBackend('\OC\Files\Storage\Local')
|
||||
->setAllowedVisibility(\OCA\Files_External\Service\BackendService::VISIBILITY_ADMIN);
|
||||
|
||||
OC_Mount_Config::registerBackend('\OC\Files\Storage\AmazonS3', [
|
||||
'backend' => (string)$l->t('Amazon S3'),
|
||||
|
@ -237,5 +244,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);
|
||||
|
|
|
@ -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,33 @@ class Application extends App {
|
|||
$c->query('Request')
|
||||
);
|
||||
});
|
||||
|
||||
$this->loadBackends();
|
||||
$this->loadAuthMechanisms();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load storage backends provided by this app
|
||||
*/
|
||||
protected function loadBackends() {
|
||||
$container = $this->getContainer();
|
||||
$service = $container->query('OCA\\Files_External\\Service\\BackendService');
|
||||
}
|
||||
|
||||
/**
|
||||
* Load authentication mechanisms provided by this app
|
||||
*/
|
||||
protected function loadAuthMechanisms() {
|
||||
$container = $this->getContainer();
|
||||
$service = $container->query('OCA\\Files_External\\Service\\BackendService');
|
||||
|
||||
$service->registerAuthMechanisms([
|
||||
// AuthMechanism::SCHEME_NULL mechanism
|
||||
$container->query('OCA\Files_External\Lib\Auth\NullMechanism'),
|
||||
|
||||
// AuthMechanism::SCHEME_BUILTIN mechanism
|
||||
$container->query('OCA\Files_External\Lib\Auth\Builtin'),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@ namespace OCA\Files_External\AppInfo;
|
|||
/**
|
||||
* @var $this \OC\Route\Router
|
||||
**/
|
||||
$application = new Application();
|
||||
$application->registerRoutes(
|
||||
\OC_Mount_Config::$app->registerRoutes(
|
||||
$this,
|
||||
array(
|
||||
'resources' => array(
|
||||
|
|
|
@ -63,7 +63,8 @@ class GlobalStoragesController extends StoragesController {
|
|||
* Create an external storage entry.
|
||||
*
|
||||
* @param string $mountPoint storage mount point
|
||||
* @param string $backendClass backend class name
|
||||
* @param string $backend backend identifier
|
||||
* @param string $authMechanism authentication mechanism identifier
|
||||
* @param array $backendOptions backend-specific options
|
||||
* @param array $mountOptions mount-specific options
|
||||
* @param array $applicableUsers users for which to mount the storage
|
||||
|
@ -74,21 +75,27 @@ class GlobalStoragesController extends StoragesController {
|
|||
*/
|
||||
public function create(
|
||||
$mountPoint,
|
||||
$backendClass,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions,
|
||||
$applicableUsers,
|
||||
$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,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions,
|
||||
$applicableUsers,
|
||||
$applicableGroups,
|
||||
$priority
|
||||
);
|
||||
if ($newStorage instanceof DataResponse) {
|
||||
return $newStorage;
|
||||
}
|
||||
|
||||
$response = $this->validate($newStorage);
|
||||
if (!empty($response)) {
|
||||
|
@ -110,7 +117,8 @@ class GlobalStoragesController extends StoragesController {
|
|||
*
|
||||
* @param int $id storage id
|
||||
* @param string $mountPoint storage mount point
|
||||
* @param string $backendClass backend class name
|
||||
* @param string $backend backend identifier
|
||||
* @param string $authMechanism authentication mechansim identifier
|
||||
* @param array $backendOptions backend-specific options
|
||||
* @param array $mountOptions mount-specific options
|
||||
* @param array $applicableUsers users for which to mount the storage
|
||||
|
@ -122,21 +130,28 @@ class GlobalStoragesController extends StoragesController {
|
|||
public function update(
|
||||
$id,
|
||||
$mountPoint,
|
||||
$backendClass,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions,
|
||||
$applicableUsers,
|
||||
$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,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions,
|
||||
$applicableUsers,
|
||||
$applicableGroups,
|
||||
$priority
|
||||
);
|
||||
if ($storage instanceof DataResponse) {
|
||||
return $storage;
|
||||
}
|
||||
$storage->setId($id);
|
||||
|
||||
$response = $this->validate($storage);
|
||||
if (!empty($response)) {
|
||||
|
|
|
@ -32,6 +32,10 @@ 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;
|
||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||
use \OCP\Files\StorageNotAvailableException;
|
||||
use \OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
|
||||
|
||||
/**
|
||||
* Base class for storages controllers
|
||||
|
@ -71,6 +75,51 @@ abstract class StoragesController extends Controller {
|
|||
$this->service = $storagesService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a storage from its parameters
|
||||
*
|
||||
* @param string $mountPoint storage mount point
|
||||
* @param string $backend backend identifier
|
||||
* @param string $authMechanism authentication mechanism identifier
|
||||
* @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,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions = null,
|
||||
$applicableUsers = null,
|
||||
$applicableGroups = null,
|
||||
$priority = null
|
||||
) {
|
||||
try {
|
||||
return $this->service->createStorage(
|
||||
$mountPoint,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions,
|
||||
$applicableUsers,
|
||||
$applicableGroups,
|
||||
$priority
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return new DataResponse(
|
||||
[
|
||||
'message' => (string)$this->l10n->t('Invalid backend or authentication mechanism class')
|
||||
],
|
||||
Http::STATUS_UNPROCESSABLE_ENTITY
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate storage config
|
||||
*
|
||||
|
@ -89,18 +138,39 @@ 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();
|
||||
/** @var AuthMechanism */
|
||||
$authMechanism = $storage->getAuthMechanism();
|
||||
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()->getIdentifier()
|
||||
])
|
||||
),
|
||||
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
|
||||
);
|
||||
}
|
||||
if (!$authMechanism->validateStorage($storage)) {
|
||||
// unsatisfied parameters
|
||||
return new DataResponse(
|
||||
[
|
||||
'message' => (string)$this->l10n->t('Unsatisfied authentication mechanism parameters')
|
||||
],
|
||||
Http::STATUS_UNPROCESSABLE_ENTITY
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -114,14 +184,27 @@ abstract class StoragesController extends Controller {
|
|||
* @param StorageConfig $storage storage configuration
|
||||
*/
|
||||
protected function updateStorageStatus(StorageConfig &$storage) {
|
||||
// update status (can be time-consuming)
|
||||
$storage->setStatus(
|
||||
\OC_Mount_Config::getBackendStatus(
|
||||
$storage->getBackendClass(),
|
||||
$storage->getBackendOptions(),
|
||||
false
|
||||
)
|
||||
);
|
||||
try {
|
||||
/** @var AuthMechanism */
|
||||
$authMechanism = $storage->getAuthMechanism();
|
||||
$authMechanism->manipulateStorageConfig($storage);
|
||||
/** @var Backend */
|
||||
$backend = $storage->getBackend();
|
||||
$backend->manipulateStorageConfig($storage);
|
||||
|
||||
// update status (can be time-consuming)
|
||||
$storage->setStatus(
|
||||
\OC_Mount_Config::getBackendStatus(
|
||||
$backend->getStorageClass(),
|
||||
$storage->getBackendOptions(),
|
||||
false
|
||||
)
|
||||
);
|
||||
} catch (InsufficientDataForMeaningfulAnswerException $e) {
|
||||
$storage->setStatus(\OC_Mount_Config::STATUS_INDETERMINATE);
|
||||
} catch (StorageNotAvailableException $e) {
|
||||
$storage->setStatus(\OC_Mount_Config::STATUS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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()->getIdentifier()
|
||||
])
|
||||
),
|
||||
Http::STATUS_UNPROCESSABLE_ENTITY
|
||||
);
|
||||
|
@ -103,7 +108,8 @@ class UserStoragesController extends StoragesController {
|
|||
* Create an external storage entry.
|
||||
*
|
||||
* @param string $mountPoint storage mount point
|
||||
* @param string $backendClass backend class name
|
||||
* @param string $backend backend identifier
|
||||
* @param string $authMechanism authentication mechanism identifier
|
||||
* @param array $backendOptions backend-specific options
|
||||
* @param array $mountOptions backend-specific mount options
|
||||
*
|
||||
|
@ -113,15 +119,21 @@ class UserStoragesController extends StoragesController {
|
|||
*/
|
||||
public function create(
|
||||
$mountPoint,
|
||||
$backendClass,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions
|
||||
) {
|
||||
$newStorage = new StorageConfig();
|
||||
$newStorage->setMountPoint($mountPoint);
|
||||
$newStorage->setBackendClass($backendClass);
|
||||
$newStorage->setBackendOptions($backendOptions);
|
||||
$newStorage->setMountOptions($mountOptions);
|
||||
$newStorage = $this->createStorage(
|
||||
$mountPoint,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions
|
||||
);
|
||||
if ($newStorage instanceOf DataResponse) {
|
||||
return $newStorage;
|
||||
}
|
||||
|
||||
$response = $this->validate($newStorage);
|
||||
if (!empty($response)) {
|
||||
|
@ -142,7 +154,8 @@ class UserStoragesController extends StoragesController {
|
|||
*
|
||||
* @param int $id storage id
|
||||
* @param string $mountPoint storage mount point
|
||||
* @param string $backendClass backend class name
|
||||
* @param string $backend backend identifier
|
||||
* @param string $authMechanism authentication mechanism identifier
|
||||
* @param array $backendOptions backend-specific options
|
||||
* @param array $mountOptions backend-specific mount options
|
||||
*
|
||||
|
@ -153,15 +166,22 @@ class UserStoragesController extends StoragesController {
|
|||
public function update(
|
||||
$id,
|
||||
$mountPoint,
|
||||
$backendClass,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions
|
||||
) {
|
||||
$storage = new StorageConfig($id);
|
||||
$storage->setMountPoint($mountPoint);
|
||||
$storage->setBackendClass($backendClass);
|
||||
$storage->setBackendOptions($backendOptions);
|
||||
$storage->setMountOptions($mountOptions);
|
||||
$storage = $this->createStorage(
|
||||
$mountPoint,
|
||||
$backend,
|
||||
$authMechanism,
|
||||
$backendOptions,
|
||||
$mountOptions
|
||||
);
|
||||
if ($storage instanceOf DataResponse) {
|
||||
return $storage;
|
||||
}
|
||||
$storage->setId($id);
|
||||
|
||||
$response = $this->validate($storage);
|
||||
if (!empty($response)) {
|
||||
|
|
|
@ -191,7 +191,8 @@ var StorageConfig = function(id) {
|
|||
StorageConfig.Status = {
|
||||
IN_PROGRESS: -1,
|
||||
SUCCESS: 0,
|
||||
ERROR: 1
|
||||
ERROR: 1,
|
||||
INDETERMINATE: 2
|
||||
};
|
||||
/**
|
||||
* @memberof OCA.External.Settings
|
||||
|
@ -214,11 +215,18 @@ StorageConfig.prototype = {
|
|||
mountPoint: '',
|
||||
|
||||
/**
|
||||
* Backend class name
|
||||
* Backend
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
backendClass: null,
|
||||
backend: null,
|
||||
|
||||
/**
|
||||
* Authentication mechanism
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
authMechanism: null,
|
||||
|
||||
/**
|
||||
* Backend-specific configuration
|
||||
|
@ -272,7 +280,8 @@ StorageConfig.prototype = {
|
|||
getData: function() {
|
||||
var data = {
|
||||
mountPoint: this.mountPoint,
|
||||
backendClass: this.backendClass,
|
||||
backend: this.backend,
|
||||
authMechanism: this.authMechanism,
|
||||
backendOptions: this.backendOptions
|
||||
};
|
||||
if (this.id) {
|
||||
|
@ -579,6 +588,13 @@ MountConfigListView.prototype = {
|
|||
*/
|
||||
_allBackends: null,
|
||||
|
||||
/**
|
||||
* List of all supported authentication mechanisms
|
||||
*
|
||||
* @type Object.<string,Object>
|
||||
*/
|
||||
_allAuthMechanisms: null,
|
||||
|
||||
_encryptionEnabled: false,
|
||||
|
||||
/**
|
||||
|
@ -605,6 +621,7 @@ MountConfigListView.prototype = {
|
|||
// read the backend config that was carefully crammed
|
||||
// into the data-configurations attribute of the select
|
||||
this._allBackends = this.$el.find('.selectBackend').data('configurations');
|
||||
this._allAuthMechanisms = this.$el.find('#addMountPoint .authentication').data('mechanisms');
|
||||
|
||||
//initialize hidden input field with list of users and groups
|
||||
this.$el.find('tr:not(#addMountPoint)').each(function(i,tr) {
|
||||
|
@ -660,6 +677,7 @@ MountConfigListView.prototype = {
|
|||
});
|
||||
|
||||
this.$el.on('change', '.selectBackend', _.bind(this._onSelectBackend, this));
|
||||
this.$el.on('change', '.selectAuthMechanism', _.bind(this._onSelectAuthMechanism, this));
|
||||
},
|
||||
|
||||
_onChange: function(event) {
|
||||
|
@ -687,47 +705,34 @@ MountConfigListView.prototype = {
|
|||
$el.find('tbody').append($tr.clone());
|
||||
$el.find('tbody tr').last().find('.mountPoint input').val('');
|
||||
var selected = $target.find('option:selected').text();
|
||||
var backendClass = $target.val();
|
||||
var backend = $target.val();
|
||||
$tr.find('.backend').text(selected);
|
||||
if ($tr.find('.mountPoint input').val() === '') {
|
||||
$tr.find('.mountPoint input').val(this._suggestMountPoint(selected));
|
||||
}
|
||||
$tr.addClass(backendClass);
|
||||
$tr.find('.backend').data('class', backendClass);
|
||||
var configurations = this._allBackends;
|
||||
var $td = $tr.find('td.configuration');
|
||||
$.each(configurations, function(backend, parameters) {
|
||||
if (backend === backendClass) {
|
||||
$.each(parameters['configuration'], function(parameter, placeholder) {
|
||||
var is_optional = false;
|
||||
if (placeholder.indexOf('&') === 0) {
|
||||
is_optional = true;
|
||||
placeholder = placeholder.substring(1);
|
||||
}
|
||||
var newElement;
|
||||
if (placeholder.indexOf('*') === 0) {
|
||||
var class_string = is_optional ? ' optional' : '';
|
||||
newElement = $('<input type="password" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
|
||||
} else if (placeholder.indexOf('!') === 0) {
|
||||
newElement = $('<label><input type="checkbox" class="added" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');
|
||||
} else if (placeholder.indexOf('#') === 0) {
|
||||
newElement = $('<input type="hidden" class="added" data-parameter="'+parameter+'" />');
|
||||
} else {
|
||||
var class_string = is_optional ? ' optional' : '';
|
||||
newElement = $('<input type="text" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
|
||||
}
|
||||
highlightInput(newElement);
|
||||
$td.append(newElement);
|
||||
});
|
||||
var priorityEl = $('<input type="hidden" class="priority" value="' + parameters['priority'] + '" />');
|
||||
$tr.append(priorityEl);
|
||||
if (parameters['custom'] && $el.find('tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length === 1) {
|
||||
OC.addScript('files_external', parameters['custom']);
|
||||
}
|
||||
$td.children().not('[type=hidden]').first().focus();
|
||||
return false;
|
||||
$tr.addClass(backend);
|
||||
$tr.find('.backend').data('class', backend);
|
||||
var backendConfiguration = this._allBackends[backend];
|
||||
|
||||
var selectAuthMechanism = $('<select class="selectAuthMechanism"></select>');
|
||||
$.each(this._allAuthMechanisms, function(authClass, authMechanism) {
|
||||
if (backendConfiguration['authSchemes'][authMechanism['scheme']]) {
|
||||
selectAuthMechanism.append(
|
||||
$('<option value="'+authClass+'" data-scheme="'+authMechanism['scheme']+'">'+authMechanism['name']+'</option>')
|
||||
);
|
||||
}
|
||||
});
|
||||
$tr.find('td.authentication').append(selectAuthMechanism);
|
||||
|
||||
var $td = $tr.find('td.configuration');
|
||||
$.each(backendConfiguration['configuration'], _.partial(this.writeParameterInput, $td));
|
||||
|
||||
selectAuthMechanism.trigger('change'); // generate configuration parameters for auth mechanism
|
||||
|
||||
var priorityEl = $('<input type="hidden" class="priority" value="' + backendConfiguration['priority'] + '" />');
|
||||
$tr.append(priorityEl);
|
||||
$td.children().not('[type=hidden]').first().focus();
|
||||
|
||||
$tr.find('td').last().attr('class', 'remove');
|
||||
$tr.find('td.mountOptionsToggle').removeClass('hidden');
|
||||
$tr.find('td').last().removeAttr('style');
|
||||
|
@ -736,6 +741,41 @@ MountConfigListView.prototype = {
|
|||
addSelect2($tr.find('.applicableUsers'), this._userListLimit);
|
||||
},
|
||||
|
||||
_onSelectAuthMechanism: function(event) {
|
||||
var $target = $(event.target);
|
||||
var $tr = $target.closest('tr');
|
||||
|
||||
var authMechanism = $target.val();
|
||||
var authMechanismConfiguration = this._allAuthMechanisms[authMechanism];
|
||||
var $td = $tr.find('td.configuration');
|
||||
$td.find('.auth-param').remove();
|
||||
|
||||
$.each(authMechanismConfiguration['configuration'], _.partial(
|
||||
this.writeParameterInput, $td, _, _, ['auth-param']
|
||||
));
|
||||
},
|
||||
|
||||
writeParameterInput: function($td, parameter, placeholder, classes) {
|
||||
classes = $.isArray(classes) ? classes : [];
|
||||
classes.push('added');
|
||||
if (placeholder.indexOf('&') === 0) {
|
||||
classes.push('optional');
|
||||
placeholder = placeholder.substring(1);
|
||||
}
|
||||
var newElement;
|
||||
if (placeholder.indexOf('*') === 0) {
|
||||
newElement = $('<input type="password" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
|
||||
} else if (placeholder.indexOf('!') === 0) {
|
||||
newElement = $('<label><input type="checkbox" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');
|
||||
} else if (placeholder.indexOf('#') === 0) {
|
||||
newElement = $('<input type="hidden" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />');
|
||||
} else {
|
||||
newElement = $('<input type="text" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
|
||||
}
|
||||
highlightInput(newElement);
|
||||
$td.append(newElement);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the storage model from the given row
|
||||
*
|
||||
|
@ -750,7 +790,8 @@ MountConfigListView.prototype = {
|
|||
}
|
||||
var storage = new this._storageConfigClass(storageId);
|
||||
storage.mountPoint = $tr.find('.mountPoint input').val();
|
||||
storage.backendClass = $tr.find('.backend').data('class');
|
||||
storage.backend = $tr.find('.backend').data('class');
|
||||
storage.authMechanism = $tr.find('.selectAuthMechanism').val();
|
||||
|
||||
var classOptions = {};
|
||||
var configuration = $tr.find('.configuration input');
|
||||
|
@ -903,7 +944,7 @@ MountConfigListView.prototype = {
|
|||
*/
|
||||
updateStatus: function($tr, status) {
|
||||
var $statusSpan = $tr.find('.status span');
|
||||
$statusSpan.removeClass('success error loading-small');
|
||||
$statusSpan.removeClass('loading-small success indeterminate error');
|
||||
switch (status) {
|
||||
case StorageConfig.Status.IN_PROGRESS:
|
||||
$statusSpan.addClass('loading-small');
|
||||
|
@ -911,6 +952,9 @@ MountConfigListView.prototype = {
|
|||
case StorageConfig.Status.SUCCESS:
|
||||
$statusSpan.addClass('success');
|
||||
break;
|
||||
case StorageConfig.Status.INDETERMINATE:
|
||||
$statusSpan.addClass('indeterminate');
|
||||
break;
|
||||
default:
|
||||
$statusSpan.addClass('error');
|
||||
}
|
||||
|
|
116
apps/files_external/lib/auth/authmechanism.php
Normal file
116
apps/files_external/lib/auth/authmechanism.php
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?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\Auth;
|
||||
|
||||
use \OCA\Files_External\Lib\StorageConfig;
|
||||
use \OCA\Files_External\Lib\VisibilityTrait;
|
||||
use \OCA\Files_External\Lib\IdentifierTrait;
|
||||
use \OCA\Files_External\Lib\FrontendDefinitionTrait;
|
||||
use \OCA\Files_External\Lib\StorageModifierTrait;
|
||||
|
||||
/**
|
||||
* Authentication mechanism
|
||||
*
|
||||
* An authentication mechanism can have services injected during construction,
|
||||
* such as \OCP\IDB for database operations. This allows an authentication
|
||||
* mechanism to perform advanced operations based on provided information.
|
||||
*
|
||||
* An authenication scheme defines the parameter interface, common to the
|
||||
* storage implementation, the backend and the authentication mechanism.
|
||||
* A storage implementation expects parameters according to the authentication
|
||||
* scheme, which are provided from the authentication mechanism.
|
||||
*
|
||||
* This class uses the following traits:
|
||||
* - VisibilityTrait
|
||||
* Restrict usage to admin-only/none
|
||||
* - FrontendDefinitionTrait
|
||||
* Specify configuration parameters and other definitions
|
||||
* - StorageModifierTrait
|
||||
* Object can affect storage mounting
|
||||
*/
|
||||
class AuthMechanism implements \JsonSerializable {
|
||||
|
||||
/** Standard authentication schemes */
|
||||
const SCHEME_NULL = 'null';
|
||||
const SCHEME_BUILTIN = 'builtin';
|
||||
const SCHEME_PASSWORD = 'password';
|
||||
const SCHEME_OAUTH1 = 'oauth1';
|
||||
const SCHEME_OAUTH2 = 'oauth2';
|
||||
const SCHEME_PUBLICKEY = 'publickey';
|
||||
const SCHEME_OPENSTACK = 'openstack';
|
||||
|
||||
use VisibilityTrait;
|
||||
use FrontendDefinitionTrait;
|
||||
use StorageModifierTrait;
|
||||
use IdentifierTrait;
|
||||
|
||||
/** @var string */
|
||||
protected $scheme;
|
||||
|
||||
/**
|
||||
* Get the authentication scheme implemented
|
||||
* See self::SCHEME_* constants
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme() {
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @return self
|
||||
*/
|
||||
public function setScheme($scheme) {
|
||||
$this->scheme = $scheme;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize into JSON for client-side JS
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize() {
|
||||
$data = $this->jsonSerializeDefinition();
|
||||
$data['scheme'] = $this->getScheme();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if parameters are satisfied in a StorageConfig
|
||||
*
|
||||
* @param StorageConfig $storage
|
||||
* @return bool
|
||||
*/
|
||||
public function validateStorage(StorageConfig $storage) {
|
||||
// does the backend actually support this scheme
|
||||
$supportedSchemes = $storage->getBackend()->getAuthSchemes();
|
||||
if (!isset($supportedSchemes[$this->getScheme()])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->validateStorageDefinition($storage);
|
||||
}
|
||||
|
||||
}
|
41
apps/files_external/lib/auth/builtin.php
Normal file
41
apps/files_external/lib/auth/builtin.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?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\Auth;
|
||||
|
||||
use \OCP\IL10N;
|
||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||
use \OCA\Files_external\Lib\StorageConfig;
|
||||
|
||||
/**
|
||||
* Builtin authentication mechanism, for legacy backends
|
||||
*/
|
||||
class Builtin extends AuthMechanism {
|
||||
|
||||
public function __construct(IL10N $l) {
|
||||
$this
|
||||
->setIdentifier('builtin::builtin')
|
||||
->setScheme(self::SCHEME_BUILTIN)
|
||||
->setText($l->t('Builtin'))
|
||||
;
|
||||
}
|
||||
|
||||
}
|
41
apps/files_external/lib/auth/nullmechanism.php
Normal file
41
apps/files_external/lib/auth/nullmechanism.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?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\Auth;
|
||||
|
||||
use \OCP\IL10N;
|
||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||
use \OCA\Files_external\Lib\StorageConfig;
|
||||
|
||||
/**
|
||||
* Null authentication mechanism
|
||||
*/
|
||||
class NullMechanism extends AuthMechanism {
|
||||
|
||||
public function __construct(IL10N $l) {
|
||||
$this
|
||||
->setIdentifier('null::null')
|
||||
->setScheme(self::SCHEME_NULL)
|
||||
->setText($l->t('None'))
|
||||
;
|
||||
}
|
||||
|
||||
}
|
164
apps/files_external/lib/backend/backend.php
Normal file
164
apps/files_external/lib/backend/backend.php
Normal file
|
@ -0,0 +1,164 @@
|
|||
<?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;
|
||||
use \OCA\Files_External\Lib\IdentifierTrait;
|
||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||
|
||||
/**
|
||||
* Storage backend
|
||||
*
|
||||
* A backend can have services injected during construction,
|
||||
* such as \OCP\IDB for database operations. This allows a backend
|
||||
* to perform advanced operations based on provided information.
|
||||
*
|
||||
* An authenication scheme defines the parameter interface, common to the
|
||||
* storage implementation, the backend and the authentication mechanism.
|
||||
* A storage implementation expects parameters according to the authentication
|
||||
* scheme, which are provided from the authentication mechanism.
|
||||
*
|
||||
* This class uses the following traits:
|
||||
* - VisibilityTrait
|
||||
* Restrict usage to admin-only/none
|
||||
* - FrontendDefinitionTrait
|
||||
* Specify configuration parameters and other definitions
|
||||
* - PriorityTrait
|
||||
* Allow objects to prioritize over others with the same mountpoint
|
||||
* - DependencyTrait
|
||||
* The object requires certain dependencies to be met
|
||||
* - StorageModifierTrait
|
||||
* Object can affect storage mounting
|
||||
*/
|
||||
class Backend implements \JsonSerializable {
|
||||
|
||||
use VisibilityTrait;
|
||||
use FrontendDefinitionTrait;
|
||||
use PriorityTrait;
|
||||
use DependencyTrait;
|
||||
use StorageModifierTrait;
|
||||
use IdentifierTrait;
|
||||
|
||||
/** @var string storage class */
|
||||
private $storageClass;
|
||||
|
||||
/** @var array 'scheme' => true, supported authentication schemes */
|
||||
private $authSchemes = [];
|
||||
|
||||
/** @var AuthMechanism|callable authentication mechanism fallback */
|
||||
private $legacyAuthMechanism;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStorageClass() {
|
||||
return $this->storageClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @return self
|
||||
*/
|
||||
public function setStorageClass($class) {
|
||||
$this->storageClass = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthSchemes() {
|
||||
if (empty($this->authSchemes)) {
|
||||
return [AuthMechanism::SCHEME_NULL => true];
|
||||
}
|
||||
return $this->authSchemes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @return self
|
||||
*/
|
||||
public function addAuthScheme($scheme) {
|
||||
$this->authSchemes[$scheme] = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters storage parameters, for dynamic mechanism selection
|
||||
* @return AuthMechanism
|
||||
*/
|
||||
public function getLegacyAuthMechanism(array $parameters = []) {
|
||||
if (is_callable($this->legacyAuthMechanism)) {
|
||||
return call_user_func($this->legacyAuthMechanism, $parameters);
|
||||
}
|
||||
return $this->legacyAuthMechanism;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AuthMechanism $authMechanism
|
||||
* @return self
|
||||
*/
|
||||
public function setLegacyAuthMechanism(AuthMechanism $authMechanism) {
|
||||
$this->legacyAuthMechanism = $authMechanism;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $callback dynamic auth mechanism selection
|
||||
* @return self
|
||||
*/
|
||||
public function setLegacyAuthMechanismCallback(callable $callback) {
|
||||
$this->legacyAuthMechanism = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
$data['authSchemes'] = $this->getAuthSchemes();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if parameters are satisfied in a StorageConfig
|
||||
*
|
||||
* @param StorageConfig $storage
|
||||
* @return bool
|
||||
*/
|
||||
public function validateStorage(StorageConfig $storage) {
|
||||
return $this->validateStorageDefinition($storage);
|
||||
}
|
||||
|
||||
}
|
||||
|
85
apps/files_external/lib/backend/legacybackend.php
Normal file
85
apps/files_external/lib/backend/legacybackend.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?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\DefinitionParameter;
|
||||
use \OCA\Files_External\Lib\Backend\Backend;
|
||||
use \OCA\Files_External\Lib\Auth\Builtin;
|
||||
|
||||
/**
|
||||
* Legacy compatibility for OC_Mount_Config::registerBackend()
|
||||
*/
|
||||
class LegacyBackend extends Backend {
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param array $definition
|
||||
* @param Builtin $authMechanism
|
||||
*/
|
||||
public function __construct($class, array $definition, Builtin $authMechanism) {
|
||||
$this
|
||||
->setIdentifier($class)
|
||||
->setStorageClass($class)
|
||||
->setText($definition['backend'])
|
||||
->addAuthScheme(Builtin::SCHEME_BUILTIN)
|
||||
->setLegacyAuthMechanism($authMechanism)
|
||||
;
|
||||
|
||||
foreach ($definition['configuration'] as $name => $placeholder) {
|
||||
$flags = DefinitionParameter::FLAG_NONE;
|
||||
$type = DefinitionParameter::VALUE_TEXT;
|
||||
if ($placeholder[0] === '&') {
|
||||
$flags = DefinitionParameter::FLAG_OPTIONAL;
|
||||
$placeholder = substr($placeholder, 1);
|
||||
}
|
||||
switch ($placeholder[0]) {
|
||||
case '!':
|
||||
$type = DefinitionParameter::VALUE_BOOLEAN;
|
||||
$placeholder = substr($placeholder, 1);
|
||||
break;
|
||||
case '*':
|
||||
$type = DefinitionParameter::VALUE_PASSWORD;
|
||||
$placeholder = substr($placeholder, 1);
|
||||
break;
|
||||
case '#':
|
||||
$type = DefinitionParameter::VALUE_HIDDEN;
|
||||
$placeholder = substr($placeholder, 1);
|
||||
break;
|
||||
}
|
||||
$this->addParameter((new DefinitionParameter($name, $placeholder))
|
||||
->setType($type)
|
||||
->setFlags($flags)
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($definition['priority'])) {
|
||||
$this->setPriority($definition['priority']);
|
||||
}
|
||||
if (isset($definition['custom'])) {
|
||||
$this->setCustomJs($definition['custom']);
|
||||
}
|
||||
if (isset($definition['has_dependencies']) && $definition['has_dependencies']) {
|
||||
$this->setDependencyCheck($class . '::checkDependencies');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,11 @@
|
|||
*/
|
||||
|
||||
use phpseclib\Crypt\AES;
|
||||
use \OCA\Files_External\Appinfo\Application;
|
||||
use \OCA\Files_External\Lib\BackendConfig;
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
use \OCA\Files_External\Lib\Backend\LegacyBackend;
|
||||
use \OCA\Files_External\Lib\StorageConfig;
|
||||
|
||||
/**
|
||||
* Class to configure mount.json globally and for users
|
||||
|
@ -47,75 +52,30 @@ class OC_Mount_Config {
|
|||
// getBackendStatus return types
|
||||
const STATUS_SUCCESS = 0;
|
||||
const STATUS_ERROR = 1;
|
||||
const STATUS_INDETERMINATE = 2;
|
||||
|
||||
// whether to skip backend test (for unit tests, as this static class is not mockable)
|
||||
public static $skipTest = false;
|
||||
|
||||
private static $backends = array();
|
||||
/** @var Application */
|
||||
public static $app;
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param array $definition
|
||||
* @return bool
|
||||
* @deprecated 8.2.0 use \OCA\Files_External\Service\BackendService::registerBackend()
|
||||
*/
|
||||
public static function registerBackend($class, $definition) {
|
||||
if (!isset($definition['backend'])) {
|
||||
return false;
|
||||
}
|
||||
$backendService = self::$app->getContainer()->query('OCA\Files_External\Service\BackendService');
|
||||
$auth = self::$app->getContainer()->query('OCA\Files_External\Lib\Auth\Builtin');
|
||||
|
||||
$backendService->registerBackend(new LegacyBackend($class, $definition, $auth));
|
||||
|
||||
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
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Hook that mounts the given user's visible mount points
|
||||
*
|
||||
* @param array $data
|
||||
|
@ -152,138 +112,106 @@ class OC_Mount_Config {
|
|||
* Returns the mount points for the given user.
|
||||
* The mount point is relative to the data directory.
|
||||
*
|
||||
* @param string $user user
|
||||
* @param string $uid user
|
||||
* @return array of mount point string as key, mountpoint config as value
|
||||
*
|
||||
* @deprecated 8.2.0 use UserGlobalStoragesService::getAllStorages() and UserStoragesService::getAllStorages()
|
||||
*/
|
||||
public static function getAbsoluteMountPoints($user) {
|
||||
public static function getAbsoluteMountPoints($uid) {
|
||||
$mountPoints = array();
|
||||
|
||||
$backends = self::getBackends();
|
||||
$userGlobalStoragesService = self::$app->getContainer()->query('OCA\Files_External\Service\UserGlobalStoragesService');
|
||||
$userStoragesService = self::$app->getContainer()->query('OCA\Files_External\Service\UserStoragesService');
|
||||
$user = self::$app->getContainer()->query('OCP\IUserManager')->get($uid);
|
||||
|
||||
// Load system mount points
|
||||
$mountConfig = self::readData();
|
||||
$userGlobalStoragesService->setUser($user);
|
||||
$userStoragesService->setUser($user);
|
||||
|
||||
// Global mount points (is this redundant?)
|
||||
if (isset($mountConfig[self::MOUNT_TYPE_GLOBAL])) {
|
||||
foreach ($mountConfig[self::MOUNT_TYPE_GLOBAL] as $mountPoint => $options) {
|
||||
$options['personal'] = false;
|
||||
$options['options'] = self::decryptPasswords($options['options']);
|
||||
if (!isset($options['priority'])) {
|
||||
$options['priority'] = $backends[$options['class']]['priority'];
|
||||
}
|
||||
|
||||
// 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'];
|
||||
$mountPoints[$mountPoint] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
// All user mount points
|
||||
if (isset($mountConfig[self::MOUNT_TYPE_USER]) && isset($mountConfig[self::MOUNT_TYPE_USER]['all'])) {
|
||||
$mounts = $mountConfig[self::MOUNT_TYPE_USER]['all'];
|
||||
foreach ($mounts as $mountPoint => $options) {
|
||||
$mountPoint = self::setUserVars($user, $mountPoint);
|
||||
foreach ($options as &$option) {
|
||||
$option = self::setUserVars($user, $option);
|
||||
}
|
||||
$options['personal'] = false;
|
||||
$options['options'] = self::decryptPasswords($options['options']);
|
||||
if (!isset($options['priority'])) {
|
||||
$options['priority'] = $backends[$options['class']]['priority'];
|
||||
}
|
||||
|
||||
// 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'];
|
||||
$mountPoints[$mountPoint] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Group mount points
|
||||
if (isset($mountConfig[self::MOUNT_TYPE_GROUP])) {
|
||||
foreach ($mountConfig[self::MOUNT_TYPE_GROUP] as $group => $mounts) {
|
||||
if (\OC_Group::inGroup($user, $group)) {
|
||||
foreach ($mounts as $mountPoint => $options) {
|
||||
$mountPoint = self::setUserVars($user, $mountPoint);
|
||||
foreach ($options as &$option) {
|
||||
$option = self::setUserVars($user, $option);
|
||||
}
|
||||
$options['personal'] = false;
|
||||
$options['options'] = self::decryptPasswords($options['options']);
|
||||
if (!isset($options['priority'])) {
|
||||
$options['priority'] = $backends[$options['class']]['priority'];
|
||||
}
|
||||
|
||||
// Override if priority greater or if priority type different
|
||||
if ((!isset($mountPoints[$mountPoint]))
|
||||
|| ($options['priority'] >= $mountPoints[$mountPoint]['priority'])
|
||||
|| ($mountPoints[$mountPoint]['priority_type'] !== self::MOUNT_TYPE_GROUP)
|
||||
) {
|
||||
$options['priority_type'] = self::MOUNT_TYPE_GROUP;
|
||||
$options['backend'] = $backends[$options['class']]['backend'];
|
||||
$mountPoints[$mountPoint] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// User mount points
|
||||
if (isset($mountConfig[self::MOUNT_TYPE_USER])) {
|
||||
foreach ($mountConfig[self::MOUNT_TYPE_USER] as $mountUser => $mounts) {
|
||||
if (strtolower($mountUser) === strtolower($user)) {
|
||||
foreach ($mounts as $mountPoint => $options) {
|
||||
$mountPoint = self::setUserVars($user, $mountPoint);
|
||||
foreach ($options as &$option) {
|
||||
$option = self::setUserVars($user, $option);
|
||||
}
|
||||
$options['personal'] = false;
|
||||
$options['options'] = self::decryptPasswords($options['options']);
|
||||
if (!isset($options['priority'])) {
|
||||
$options['priority'] = $backends[$options['class']]['priority'];
|
||||
}
|
||||
|
||||
// Override if priority greater or if priority type different
|
||||
if ((!isset($mountPoints[$mountPoint]))
|
||||
|| ($options['priority'] >= $mountPoints[$mountPoint]['priority'])
|
||||
|| ($mountPoints[$mountPoint]['priority_type'] !== self::MOUNT_TYPE_USER)
|
||||
) {
|
||||
$options['priority_type'] = self::MOUNT_TYPE_USER;
|
||||
$options['backend'] = $backends[$options['class']]['backend'];
|
||||
$mountPoints[$mountPoint] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($userGlobalStoragesService->getAllStorages() as $storage) {
|
||||
$mountPoint = '/'.$uid.'/files'.$storage->getMountPoint();
|
||||
$mountEntry = self::prepareMountPointEntry($storage, false);
|
||||
foreach ($mountEntry['options'] as &$option) {
|
||||
$option = self::setUserVars($uid, $option);
|
||||
}
|
||||
$mountPoints[$mountPoint] = $mountEntry;
|
||||
}
|
||||
|
||||
$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']])) {
|
||||
$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'];
|
||||
$mountPoints[$mountPoint] = $options;
|
||||
}
|
||||
foreach ($userStoragesService->getAllStorages() as $storage) {
|
||||
$mountPoint = '/'.$uid.'/files'.$storage->getMountPoint();
|
||||
$mountEntry = self::prepareMountPointEntry($storage, true);
|
||||
foreach ($mountEntry['options'] as &$option) {
|
||||
$option = self::setUserVars($uid, $option);
|
||||
}
|
||||
$mountPoints[$mountPoint] = $mountEntry;
|
||||
}
|
||||
|
||||
$userGlobalStoragesService->resetUser();
|
||||
$userStoragesService->resetUser();
|
||||
|
||||
return $mountPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system mount points
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 8.2.0 use GlobalStoragesService::getAllStorages()
|
||||
*/
|
||||
public static function getSystemMountPoints() {
|
||||
$mountPoints = [];
|
||||
$service = self::$app->getContainer()->query('OCA\Files_External\Service\GlobalStoragesService');
|
||||
|
||||
foreach ($service->getAllStorages() as $storage) {
|
||||
$mountPoints[] = self::prepareMountPointEntry($storage, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the personal mount points of the current user
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 8.2.0 use UserStoragesService::getAllStorages()
|
||||
*/
|
||||
public static function getPersonalMountPoints() {
|
||||
$mountPoints = [];
|
||||
$service = self::$app->getContainer()->query('OCA\Files_External\Service\UserStoragesService');
|
||||
|
||||
foreach ($service->getAllStorages() as $storage) {
|
||||
$mountPoints[] = self::prepareMountPointEntry($storage, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a StorageConfig to the legacy mountPoints array format
|
||||
* There's a lot of extra information in here, to satisfy all of the legacy functions
|
||||
*
|
||||
* @param StorageConfig $storage
|
||||
* @param bool $isPersonal
|
||||
* @return array
|
||||
*/
|
||||
private static function prepareMountPointEntry(StorageConfig $storage, $isPersonal) {
|
||||
$mountEntry = [];
|
||||
|
||||
$mountEntry['mountpoint'] = substr($storage->getMountPoint(), 1); // remove leading slash
|
||||
$mountEntry['class'] = $storage->getBackend()->getIdentifier();
|
||||
$mountEntry['backend'] = $storage->getBackend()->getText();
|
||||
$mountEntry['authMechanism'] = $storage->getAuthMechanism()->getIdentifier();
|
||||
$mountEntry['personal'] = $isPersonal;
|
||||
$mountEntry['options'] = self::decryptPasswords($storage->getBackendOptions());
|
||||
$mountEntry['mountOptions'] = $storage->getMountOptions();
|
||||
$mountEntry['priority'] = $storage->getPriority();
|
||||
$mountEntry['applicable'] = [
|
||||
'groups' => $storage->getApplicableGroups(),
|
||||
'users' => $storage->getApplicableUsers(),
|
||||
];
|
||||
$mountEntry['id'] = $storage->getId();
|
||||
// $mountEntry['storage_id'] = null; // we don't store this!
|
||||
|
||||
return $mountEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* fill in the correct values for $user
|
||||
*
|
||||
|
@ -291,7 +219,7 @@ class OC_Mount_Config {
|
|||
* @param string|array $input
|
||||
* @return string
|
||||
*/
|
||||
private static function setUserVars($user, $input) {
|
||||
public static function setUserVars($user, $input) {
|
||||
if (is_array($input)) {
|
||||
foreach ($input as &$value) {
|
||||
if (is_string($value)) {
|
||||
|
@ -304,181 +232,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()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSystemMountPoints() {
|
||||
$mountPoints = self::readData();
|
||||
$backends = self::getBackends();
|
||||
$system = array();
|
||||
if (isset($mountPoints[self::MOUNT_TYPE_GROUP])) {
|
||||
foreach ($mountPoints[self::MOUNT_TYPE_GROUP] as $group => $mounts) {
|
||||
foreach ($mounts as $mountPoint => $mount) {
|
||||
// Update old classes to new namespace
|
||||
if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
|
||||
$mount['class'] = '\OC\Files\Storage\\' . substr($mount['class'], 15);
|
||||
}
|
||||
$mount['options'] = self::decryptPasswords($mount['options']);
|
||||
if (!isset($mount['priority'])) {
|
||||
$mount['priority'] = $backends[$mount['class']]['priority'];
|
||||
}
|
||||
// Remove '/$user/files/' from mount point
|
||||
$mountPoint = substr($mountPoint, 13);
|
||||
|
||||
$config = array(
|
||||
'class' => $mount['class'],
|
||||
'mountpoint' => $mountPoint,
|
||||
'backend' => $backends[$mount['class']]['backend'],
|
||||
'priority' => $mount['priority'],
|
||||
'options' => $mount['options'],
|
||||
'applicable' => array('groups' => array($group), 'users' => array())
|
||||
);
|
||||
if (isset($mount['id'])) {
|
||||
$config['id'] = (int)$mount['id'];
|
||||
}
|
||||
if (isset($mount['storage_id'])) {
|
||||
$config['storage_id'] = (int)$mount['storage_id'];
|
||||
}
|
||||
if (isset($mount['mountOptions'])) {
|
||||
$config['mountOptions'] = $mount['mountOptions'];
|
||||
}
|
||||
$hash = self::makeConfigHash($config);
|
||||
// If an existing config exists (with same class, mountpoint and options)
|
||||
if (isset($system[$hash])) {
|
||||
// add the groups into that config
|
||||
$system[$hash]['applicable']['groups']
|
||||
= array_merge($system[$hash]['applicable']['groups'], array($group));
|
||||
} else {
|
||||
$system[$hash] = $config;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($mountPoints[self::MOUNT_TYPE_USER])) {
|
||||
foreach ($mountPoints[self::MOUNT_TYPE_USER] as $user => $mounts) {
|
||||
foreach ($mounts as $mountPoint => $mount) {
|
||||
// Update old classes to new namespace
|
||||
if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
|
||||
$mount['class'] = '\OC\Files\Storage\\' . substr($mount['class'], 15);
|
||||
}
|
||||
$mount['options'] = self::decryptPasswords($mount['options']);
|
||||
if (!isset($mount['priority'])) {
|
||||
$mount['priority'] = $backends[$mount['class']]['priority'];
|
||||
}
|
||||
// Remove '/$user/files/' from mount point
|
||||
$mountPoint = substr($mountPoint, 13);
|
||||
$config = array(
|
||||
'class' => $mount['class'],
|
||||
'mountpoint' => $mountPoint,
|
||||
'backend' => $backends[$mount['class']]['backend'],
|
||||
'priority' => $mount['priority'],
|
||||
'options' => $mount['options'],
|
||||
'applicable' => array('groups' => array(), 'users' => array($user))
|
||||
);
|
||||
if (isset($mount['id'])) {
|
||||
$config['id'] = (int)$mount['id'];
|
||||
}
|
||||
if (isset($mount['storage_id'])) {
|
||||
$config['storage_id'] = (int)$mount['storage_id'];
|
||||
}
|
||||
if (isset($mount['mountOptions'])) {
|
||||
$config['mountOptions'] = $mount['mountOptions'];
|
||||
}
|
||||
$hash = self::makeConfigHash($config);
|
||||
// If an existing config exists (with same class, mountpoint and options)
|
||||
if (isset($system[$hash])) {
|
||||
// add the users into that config
|
||||
$system[$hash]['applicable']['users']
|
||||
= array_merge($system[$hash]['applicable']['users'], array($user));
|
||||
} else {
|
||||
$system[$hash] = $config;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_values($system);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the personal mount points of the current user
|
||||
* The returned array is not in the same format as getUserMountPoints()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPersonalMountPoints() {
|
||||
$mountPoints = self::readData(OCP\User::getUser());
|
||||
$backEnds = self::getBackends();
|
||||
$uid = OCP\User::getUser();
|
||||
$personal = array();
|
||||
if (isset($mountPoints[self::MOUNT_TYPE_USER][$uid])) {
|
||||
foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) {
|
||||
// Update old classes to new namespace
|
||||
if (strpos($mount['class'], 'OC_Filestorage_') !== false) {
|
||||
$mount['class'] = '\OC\Files\Storage\\' . substr($mount['class'], 15);
|
||||
}
|
||||
$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'],
|
||||
'options' => $mount['options']
|
||||
);
|
||||
if (isset($mount['id'])) {
|
||||
$config['id'] = (int)$mount['id'];
|
||||
}
|
||||
if (isset($mount['storage_id'])) {
|
||||
$config['storage_id'] = (int)$mount['storage_id'];
|
||||
}
|
||||
if (isset($mount['mountOptions'])) {
|
||||
$config['mountOptions'] = $mount['mountOptions'];
|
||||
}
|
||||
$personal[] = $config;
|
||||
}
|
||||
}
|
||||
return $personal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test connecting using the given backend configuration
|
||||
*
|
||||
|
@ -514,163 +267,6 @@ class OC_Mount_Config {
|
|||
return self::STATUS_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mount point to the filesystem
|
||||
*
|
||||
* @param string $mountPoint Mount point
|
||||
* @param string $class Backend class
|
||||
* @param array $classOptions Backend parameters for the class
|
||||
* @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
|
||||
* @param string $applicable User or group to apply mount to
|
||||
* @param bool $isPersonal Personal or system mount point i.e. is this being called from the personal or admin page
|
||||
* @param int|null $priority Mount point priority, null for default
|
||||
* @return boolean
|
||||
*
|
||||
* @deprecated use StoragesService#addStorage() instead
|
||||
*/
|
||||
public static function addMountPoint($mountPoint,
|
||||
$class,
|
||||
$classOptions,
|
||||
$mountType,
|
||||
$applicable,
|
||||
$isPersonal = false,
|
||||
$priority = null) {
|
||||
$backends = self::getBackends();
|
||||
$mountPoint = OC\Files\Filesystem::normalizePath($mountPoint);
|
||||
$relMountPoint = $mountPoint;
|
||||
if ($mountPoint === '' || $mountPoint === '/') {
|
||||
// can't mount at root folder
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($backends[$class])) {
|
||||
// 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])) {
|
||||
return false;
|
||||
}
|
||||
$mountPoint = '/' . $applicable . '/files/' . ltrim($mountPoint, '/');
|
||||
} else {
|
||||
$mountPoint = '/$user/files/' . ltrim($mountPoint, '/');
|
||||
}
|
||||
|
||||
$mount = array($applicable => array(
|
||||
$mountPoint => array(
|
||||
'class' => $class,
|
||||
'options' => self::encryptPasswords($classOptions))
|
||||
)
|
||||
);
|
||||
if (!$isPersonal && !is_null($priority)) {
|
||||
$mount[$applicable][$mountPoint]['priority'] = $priority;
|
||||
}
|
||||
|
||||
$mountPoints = self::readData($isPersonal ? OCP\User::getUser() : null);
|
||||
// who else loves multi-dimensional array ?
|
||||
$isNew = !isset($mountPoints[$mountType]) ||
|
||||
!isset($mountPoints[$mountType][$applicable]) ||
|
||||
!isset($mountPoints[$mountType][$applicable][$mountPoint]);
|
||||
$mountPoints = self::mergeMountPoints($mountPoints, $mount, $mountType);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
self::writeData($isPersonal ? OCP\User::getUser() : null, $mountPoints);
|
||||
|
||||
$result = self::getBackendStatus($class, $classOptions, $isPersonal);
|
||||
if ($result === self::STATUS_SUCCESS && $isNew) {
|
||||
\OC_Hook::emit(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_create_mount,
|
||||
array(
|
||||
\OC\Files\Filesystem::signal_param_path => $relMountPoint,
|
||||
\OC\Files\Filesystem::signal_param_mount_type => $mountType,
|
||||
\OC\Files\Filesystem::signal_param_users => $applicable,
|
||||
)
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $mountPoint Mount point
|
||||
* @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
|
||||
* @param string $applicable User or group to remove mount from
|
||||
* @param bool $isPersonal Personal or system mount point
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated use StoragesService#removeStorage() instead
|
||||
*/
|
||||
public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false) {
|
||||
// Verify that the mount point applies for the current user
|
||||
$relMountPoints = $mountPoint;
|
||||
if ($isPersonal) {
|
||||
if ($applicable != OCP\User::getUser()) {
|
||||
return false;
|
||||
}
|
||||
$mountPoint = '/' . $applicable . '/files/' . ltrim($mountPoint, '/');
|
||||
} else {
|
||||
$mountPoint = '/$user/files/' . ltrim($mountPoint, '/');
|
||||
}
|
||||
$mountPoint = \OC\Files\Filesystem::normalizePath($mountPoint);
|
||||
$mountPoints = self::readData($isPersonal ? OCP\User::getUser() : null);
|
||||
// Remove mount point
|
||||
unset($mountPoints[$mountType][$applicable][$mountPoint]);
|
||||
// Unset parent arrays if empty
|
||||
if (empty($mountPoints[$mountType][$applicable])) {
|
||||
unset($mountPoints[$mountType][$applicable]);
|
||||
if (empty($mountPoints[$mountType])) {
|
||||
unset($mountPoints[$mountType]);
|
||||
}
|
||||
}
|
||||
self::writeData($isPersonal ? OCP\User::getUser() : null, $mountPoints);
|
||||
\OC_Hook::emit(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_delete_mount,
|
||||
array(
|
||||
\OC\Files\Filesystem::signal_param_path => $relMountPoints,
|
||||
\OC\Files\Filesystem::signal_param_mount_type => $mountType,
|
||||
\OC\Files\Filesystem::signal_param_users => $applicable,
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $mountPoint Mount point
|
||||
* @param string $target The new mount point
|
||||
* @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
|
||||
* @return bool
|
||||
*/
|
||||
public static function movePersonalMountPoint($mountPoint, $target, $mountType) {
|
||||
$mountPoint = rtrim($mountPoint, '/');
|
||||
$user = OCP\User::getUser();
|
||||
$mountPoints = self::readData($user);
|
||||
if (!isset($mountPoints[$mountType][$user][$mountPoint])) {
|
||||
return false;
|
||||
}
|
||||
$mountPoints[$mountType][$user][$target] = $mountPoints[$mountType][$user][$mountPoint];
|
||||
// Remove old mount point
|
||||
unset($mountPoints[$mountType][$user][$mountPoint]);
|
||||
|
||||
self::writeData($user, $mountPoints);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the mount points in the config file into an array
|
||||
*
|
||||
|
@ -721,74 +317,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'];
|
||||
} else {
|
||||
$dependencyGroup[] = $backend;
|
||||
}
|
||||
}
|
||||
$message = '';
|
||||
$dependencyGroups = [];
|
||||
|
||||
$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>';
|
||||
foreach ($backends as $backend) {
|
||||
foreach ($backend->checkDependencies() as $dependency) {
|
||||
if ($message = $dependency->getMessage()) {
|
||||
$message .= '<br />' . $l->t('<b>Note:</b> ') . $message;
|
||||
} else {
|
||||
$dependencyGroups[$dependency->getDependency()][] = $backend;
|
||||
}
|
||||
$dependencyMessage .= '<br />' . OC_Mount_Config::getSingleDependencyMessage($l, $module, $backends);
|
||||
}
|
||||
}
|
||||
return $dependencyMessage;
|
||||
|
||||
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 $message;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -918,7 +475,8 @@ class OC_Mount_Config {
|
|||
public static function makeConfigHash($config) {
|
||||
$data = json_encode(
|
||||
array(
|
||||
'c' => $config['class'],
|
||||
'c' => $config['backend'],
|
||||
'a' => $config['authMechanism'],
|
||||
'm' => $config['mountpoint'],
|
||||
'o' => $config['options'],
|
||||
'p' => isset($config['priority']) ? $config['priority'] : -1,
|
||||
|
@ -967,7 +525,8 @@ class OC_Mount_Config {
|
|||
return false;
|
||||
}
|
||||
|
||||
$class = $options['class'];
|
||||
$service = self::$app->getContainer()->query('OCA\Files_External\Service\BackendService');
|
||||
$class = $service->getBackend($options['backend'])->getStorageClass();
|
||||
try {
|
||||
/** @var \OC\Files\Storage\Storage $storage */
|
||||
$storage = new $class($options['options']);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/**
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Robin McCorkell <rmccorkell@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
|
@ -22,16 +23,81 @@
|
|||
|
||||
namespace OCA\Files_External\Config;
|
||||
|
||||
use OCP\Files\Storage;
|
||||
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;
|
||||
use OCA\Files_External\Service\UserGlobalStoragesService;
|
||||
use OCA\Files_External\Lib\StorageConfig;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCA\Files_External\Lib\FailedStorage;
|
||||
|
||||
/**
|
||||
* Make the old files_external config work with the new public mount config api
|
||||
*/
|
||||
class ConfigAdapter implements IMountProvider {
|
||||
|
||||
/** @var UserStoragesService */
|
||||
private $userStoragesService;
|
||||
|
||||
/** @var UserGlobalStoragesService */
|
||||
private $userGlobalStoragesService;
|
||||
|
||||
/**
|
||||
* @param UserStoragesService $userStoragesService
|
||||
* @param UserGlobalStoragesService $userGlobalStoragesService
|
||||
*/
|
||||
public function __construct(
|
||||
UserStoragesService $userStoragesService,
|
||||
UserGlobalStoragesService $userGlobalStoragesService
|
||||
) {
|
||||
$this->userStoragesService = $userStoragesService;
|
||||
$this->userGlobalStoragesService = $userGlobalStoragesService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process storage ready for mounting
|
||||
*
|
||||
* @param StorageConfig $storage
|
||||
* @param IUser $user
|
||||
*/
|
||||
private function prepareStorageConfig(StorageConfig &$storage, IUser $user) {
|
||||
foreach ($storage->getBackendOptions() as $option => $value) {
|
||||
$storage->setBackendOption($option, \OC_Mount_Config::setUserVars(
|
||||
$user->getUID(), $value
|
||||
));
|
||||
}
|
||||
|
||||
$objectStore = $storage->getBackendOption('objectstore');
|
||||
if ($objectStore) {
|
||||
$objectClass = $objectStore['class'];
|
||||
$storage->setBackendOption('objectstore', new $objectClass($objectStore));
|
||||
}
|
||||
|
||||
$storage->getAuthMechanism()->manipulateStorageConfig($storage);
|
||||
$storage->getBackend()->manipulateStorageConfig($storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the storage implementation
|
||||
*
|
||||
* @param StorageConfig $storageConfig
|
||||
* @return Storage
|
||||
*/
|
||||
private function constructStorage(StorageConfig $storageConfig) {
|
||||
$class = $storageConfig->getBackend()->getStorageClass();
|
||||
$storage = new $class($storageConfig->getBackendOptions());
|
||||
|
||||
// auth mechanism should fire first
|
||||
$storage = $storageConfig->getBackend()->wrapStorage($storage);
|
||||
$storage = $storageConfig->getAuthMechanism()->wrapStorage($storage);
|
||||
|
||||
return $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all mountpoints applicable for the user
|
||||
*
|
||||
|
@ -40,20 +106,54 @@ class ConfigAdapter implements IMountProvider {
|
|||
* @return \OCP\Files\Mount\IMountPoint[]
|
||||
*/
|
||||
public function getMountsForUser(IUser $user, IStorageFactory $loader) {
|
||||
$mountPoints = \OC_Mount_Config::getAbsoluteMountPoints($user->getUID());
|
||||
$mounts = array();
|
||||
foreach ($mountPoints as $mountPoint => $options) {
|
||||
if (isset($options['options']['objectstore'])) {
|
||||
$objectClass = $options['options']['objectstore']['class'];
|
||||
$options['options']['objectstore'] = new $objectClass($options['options']['objectstore']);
|
||||
}
|
||||
$mountOptions = isset($options['mountOptions']) ? $options['mountOptions'] : [];
|
||||
if (isset($options['personal']) && $options['personal']) {
|
||||
$mounts[] = new PersonalMount($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
|
||||
} else {
|
||||
$mounts[] = new MountPoint($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
|
||||
$mounts = [];
|
||||
|
||||
$this->userStoragesService->setUser($user);
|
||||
$this->userGlobalStoragesService->setUser($user);
|
||||
|
||||
foreach ($this->userGlobalStoragesService->getAllStorages() as $storage) {
|
||||
try {
|
||||
$this->prepareStorageConfig($storage, $user);
|
||||
$impl = $this->constructStorage($storage);
|
||||
} catch (\Exception $e) {
|
||||
// propagate exception into filesystem
|
||||
$impl = new FailedStorage(['exception' => $e]);
|
||||
}
|
||||
|
||||
$mount = new MountPoint(
|
||||
$impl,
|
||||
'/'.$user->getUID().'/files' . $storage->getMountPoint(),
|
||||
null,
|
||||
$loader,
|
||||
$storage->getMountOptions()
|
||||
);
|
||||
$mounts[$storage->getMountPoint()] = $mount;
|
||||
}
|
||||
|
||||
foreach ($this->userStoragesService->getAllStorages() as $storage) {
|
||||
try {
|
||||
$this->prepareStorageConfig($storage, $user);
|
||||
$impl = $this->constructStorage($storage);
|
||||
} catch (\Exception $e) {
|
||||
// propagate exception into filesystem
|
||||
$impl = new FailedStorage(['exception' => $e]);
|
||||
}
|
||||
|
||||
$mount = new PersonalMount(
|
||||
$this->userStoragesService,
|
||||
$storage->getId(),
|
||||
$impl,
|
||||
'/'.$user->getUID().'/files' . $storage->getMountPoint(),
|
||||
null,
|
||||
$loader,
|
||||
$storage->getMountOptions()
|
||||
);
|
||||
$mounts[$storage->getMountPoint()] = $mount;
|
||||
}
|
||||
|
||||
$this->userStoragesService->resetUser();
|
||||
$this->userGlobalStoragesService->resetUser();
|
||||
|
||||
return $mounts;
|
||||
}
|
||||
}
|
||||
|
|
179
apps/files_external/lib/definitionparameter.php
Normal file
179
apps/files_external/lib/definitionparameter.php
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
86
apps/files_external/lib/dependencytrait.php
Normal file
86
apps/files_external/lib/dependencytrait.php
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
200
apps/files_external/lib/failedstorage.php
Normal file
200
apps/files_external/lib/failedstorage.php
Normal file
|
@ -0,0 +1,200 @@
|
|||
<?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\Lock\ILockingProvider;
|
||||
use \OC\Files\Storage\Common;
|
||||
use \OCP\Files\StorageNotAvailableException;
|
||||
|
||||
/**
|
||||
* Storage placeholder to represent a missing precondition, storage unavailable
|
||||
*/
|
||||
class FailedStorage extends Common {
|
||||
|
||||
/** @var \Exception */
|
||||
protected $e;
|
||||
|
||||
/**
|
||||
* @param array $params ['exception' => \Exception]
|
||||
*/
|
||||
public function __construct($params) {
|
||||
$this->e = $params['exception'];
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
// we can't return anything sane here
|
||||
return 'failedstorage';
|
||||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function rmdir($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function opendir($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function is_dir($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function is_file($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function stat($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function filetype($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function filesize($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function isCreatable($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function isReadable($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function isUpdatable($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function isDeletable($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function isSharable($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function getPermissions($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function file_exists($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function filemtime($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function file_get_contents($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function file_put_contents($path, $data) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function rename($path1, $path2) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function copy($path1, $path2) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function fopen($path, $mode) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function getMimeType($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function hash($type, $path, $raw = false) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function free_space($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function search($query) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function touch($path, $mtime = null) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function getLocalFile($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function getLocalFolder($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function hasUpdated($path, $time) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function getETag($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function getDirectDownload($path) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function verifyPath($path, $fileName) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function acquireLock($path, $type, ILockingProvider $provider) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function releaseLock($path, $type, ILockingProvider $provider) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
public function changeLock($path, $type, ILockingProvider $provider) {
|
||||
throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
|
||||
}
|
||||
|
||||
}
|
147
apps/files_external/lib/frontenddefinitiontrait.php
Normal file
147
apps/files_external/lib/frontenddefinitiontrait.php
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
68
apps/files_external/lib/identifiertrait.php
Normal file
68
apps/files_external/lib/identifiertrait.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* Trait for objects requiring an identifier (and/or identifier aliases)
|
||||
*/
|
||||
trait IdentifierTrait {
|
||||
|
||||
/** @var string */
|
||||
protected $identifier;
|
||||
|
||||
/** @var string[] */
|
||||
protected $identifierAliases = [];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier() {
|
||||
return $this->identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $identifier
|
||||
* @return self
|
||||
*/
|
||||
public function setIdentifier($identifier) {
|
||||
$this->identifier = $identifier;
|
||||
$this->identifierAliases[] = $identifier;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getIdentifierAliases() {
|
||||
return $this->identifierAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $alias
|
||||
* @return self
|
||||
*/
|
||||
public function addIdentifierAlias($alias) {
|
||||
$this->identifierAliases[] = $alias;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?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\StorageNotAvailableException;
|
||||
|
||||
/**
|
||||
* Authentication mechanism or backend has insufficient data
|
||||
*/
|
||||
class InsufficientDataForMeaningfulAnswerException extends StorageNotAvailableException {
|
||||
}
|
64
apps/files_external/lib/missingdependency.php
Normal file
64
apps/files_external/lib/missingdependency.php
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
60
apps/files_external/lib/prioritytrait.php
Normal file
60
apps/files_external/lib/prioritytrait.php
Normal file
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
namespace OCA\Files_external\Lib;
|
||||
|
||||
use \OCA\Files_External\Lib\Backend\Backend;
|
||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||
|
||||
/**
|
||||
* External storage configuration
|
||||
*/
|
||||
|
@ -34,11 +37,18 @@ class StorageConfig implements \JsonSerializable {
|
|||
private $id;
|
||||
|
||||
/**
|
||||
* Backend class name
|
||||
* Backend
|
||||
*
|
||||
* @var string
|
||||
* @var Backend
|
||||
*/
|
||||
private $backendClass;
|
||||
private $backend;
|
||||
|
||||
/**
|
||||
* Authentication mechanism
|
||||
*
|
||||
* @var AuthMechanism
|
||||
*/
|
||||
private $authMechanism;
|
||||
|
||||
/**
|
||||
* Backend options
|
||||
|
@ -138,21 +148,31 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AuthMechanism
|
||||
*/
|
||||
public function getAuthMechanism() {
|
||||
return $this->authMechanism;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AuthMechanism
|
||||
*/
|
||||
public function setAuthMechanism(AuthMechanism $authMechanism) {
|
||||
$this->authMechanism = $authMechanism;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,6 +193,25 @@ class StorageConfig implements \JsonSerializable {
|
|||
$this->backendOptions = $backendOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
|
@ -283,7 +322,8 @@ class StorageConfig implements \JsonSerializable {
|
|||
$result['id'] = $this->id;
|
||||
}
|
||||
$result['mountPoint'] = $this->mountPoint;
|
||||
$result['backendClass'] = $this->backendClass;
|
||||
$result['backend'] = $this->backend->getIdentifier();
|
||||
$result['authMechanism'] = $this->authMechanism->getIdentifier();
|
||||
$result['backendOptions'] = $this->backendOptions;
|
||||
if (!is_null($this->priority)) {
|
||||
$result['priority'] = $this->priority;
|
||||
|
|
67
apps/files_external/lib/storagemodifiertrait.php
Normal file
67
apps/files_external/lib/storagemodifiertrait.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?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;
|
||||
use \OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
|
||||
use \OCP\Files\StorageNotAvailableException;
|
||||
|
||||
/**
|
||||
* Trait for objects that can modify StorageConfigs and wrap Storages
|
||||
*
|
||||
* When a storage implementation is being prepared for use, the StorageConfig
|
||||
* is passed through manipulateStorageConfig() to update any parameters as
|
||||
* necessary. After the storage implementation has been constructed, it is
|
||||
* passed through wrapStorage(), potentially replacing the implementation with
|
||||
* a wrapped storage that changes its behaviour.
|
||||
*
|
||||
* Certain configuration options need to be set before the implementation is
|
||||
* constructed, while others are retrieved directly from the storage
|
||||
* implementation and so need a wrapper to be modified.
|
||||
*/
|
||||
trait StorageModifierTrait {
|
||||
|
||||
/**
|
||||
* Modify a StorageConfig parameters
|
||||
*
|
||||
* @param StorageConfig $storage
|
||||
* @throws InsufficientDataForMeaningfulAnswerException
|
||||
* @throws StorageNotAvailableException
|
||||
*/
|
||||
public function manipulateStorageConfig(StorageConfig &$storage) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a Storage if necessary
|
||||
*
|
||||
* @param Storage $storage
|
||||
* @return Storage
|
||||
* @throws InsufficientDataForMeaningfulAnswerException
|
||||
* @throws StorageNotAvailableException
|
||||
*/
|
||||
public function wrapStorage(Storage $storage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
}
|
||||
|
136
apps/files_external/lib/visibilitytrait.php
Normal file
136
apps/files_external/lib/visibilitytrait.php
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?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
|
||||
*
|
||||
* The standard visibility defines which users/groups can use or see the
|
||||
* object. The allowed visibility defines the maximum visibility allowed to be
|
||||
* set on the object. The standard visibility is often set dynamically by
|
||||
* stored configuration parameters that can be modified by the administrator,
|
||||
* while the allowed visibility is set directly by the object and cannot be
|
||||
* modified by the administrator.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
|
@ -24,34 +24,34 @@
|
|||
*
|
||||
*/
|
||||
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
|
||||
// we must use the same container
|
||||
$appContainer = \OC_Mount_Config::$app->getContainer();
|
||||
$backendService = $appContainer->query('OCA\Files_External\Service\BackendService');
|
||||
$userStoragesService = $appContainer->query('OCA\Files_external\Service\UserStoragesService');
|
||||
|
||||
OCP\Util::addScript('files_external', 'settings');
|
||||
OCP\Util::addStyle('files_external', 'settings');
|
||||
$backends = OC_Mount_Config::getPersonalBackends();
|
||||
|
||||
$mounts = OC_Mount_Config::getPersonalMountPoints();
|
||||
$hasId = true;
|
||||
foreach ($mounts as $mount) {
|
||||
if (!isset($mount['id'])) {
|
||||
// some mount points are missing ids
|
||||
$hasId = false;
|
||||
break;
|
||||
$backends = $backendService->getBackendsVisibleFor(BackendService::VISIBILITY_PERSONAL);
|
||||
$authMechanisms = $backendService->getAuthMechanismsVisibleFor(BackendService::VISIBILITY_PERSONAL);
|
||||
foreach ($backends as $backend) {
|
||||
if ($backend->getCustomJs()) {
|
||||
\OCP\Util::addScript('files_external', $backend->getCustomJs());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
foreach ($authMechanisms as $authMechanism) {
|
||||
if ($authMechanism->getCustomJs()) {
|
||||
\OCP\Util::addScript('files_external', $authMechanism->getCustomJs());
|
||||
}
|
||||
}
|
||||
|
||||
$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('storages', $userStoragesService->getAllStorages());
|
||||
$tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends()));
|
||||
$tmpl->assign('backends', $backends);
|
||||
$tmpl->assign('authMechanisms', $authMechanisms);
|
||||
return $tmpl->fetchPage();
|
||||
|
|
275
apps/files_external/service/backendservice.php
Normal file
275
apps/files_external/service/backendservice.php
Normal file
|
@ -0,0 +1,275 @@
|
|||
<?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;
|
||||
use \OCA\Files_External\Lib\Auth\AuthMechanism;
|
||||
|
||||
/**
|
||||
* 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 = [];
|
||||
|
||||
/** @var AuthMechanism[] */
|
||||
private $authMechanisms = [];
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
foreach ($backend->getIdentifierAliases() as $alias) {
|
||||
$this->backends[$alias] = $backend;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Backend[] $backends
|
||||
*/
|
||||
public function registerBackends(array $backends) {
|
||||
foreach ($backends as $backend) {
|
||||
$this->registerBackend($backend);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Register an authentication mechanism
|
||||
*
|
||||
* @param AuthMechanism $authMech
|
||||
*/
|
||||
public function registerAuthMechanism(AuthMechanism $authMech) {
|
||||
if (!$this->isAllowedAuthMechanism($authMech)) {
|
||||
$authMech->removeVisibility(BackendService::VISIBILITY_PERSONAL);
|
||||
}
|
||||
foreach ($authMech->getIdentifierAliases() as $alias) {
|
||||
$this->authMechanisms[$alias] = $authMech;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AuthMechanism[] $mechanisms
|
||||
*/
|
||||
public function registerAuthMechanisms(array $mechanisms) {
|
||||
foreach ($mechanisms as $mechanism) {
|
||||
$this->registerAuthMechanism($mechanism);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all backends
|
||||
*
|
||||
* @return Backend[]
|
||||
*/
|
||||
public function getBackends() {
|
||||
// only return real identifiers, no aliases
|
||||
$backends = [];
|
||||
foreach ($this->backends as $backend) {
|
||||
$backends[$backend->getIdentifier()] = $backend;
|
||||
}
|
||||
return $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 $identifier
|
||||
* @return Backend|null
|
||||
*/
|
||||
public function getBackend($identifier) {
|
||||
if (isset($this->backends[$identifier])) {
|
||||
return $this->backends[$identifier];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all authentication mechanisms
|
||||
*
|
||||
* @return AuthMechanism[]
|
||||
*/
|
||||
public function getAuthMechanisms() {
|
||||
// only return real identifiers, no aliases
|
||||
$mechanisms = [];
|
||||
foreach ($this->authMechanisms as $mechanism) {
|
||||
$mechanisms[$mechanism->getIdentifier()] = $mechanism;
|
||||
}
|
||||
return $mechanisms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all authentication mechanisms for schemes
|
||||
*
|
||||
* @param string[] $schemes
|
||||
* @return AuthMechanism[]
|
||||
*/
|
||||
public function getAuthMechanismsByScheme(array $schemes) {
|
||||
return array_filter($this->getAuthMechanisms(), function($authMech) use ($schemes) {
|
||||
return in_array($authMech->getScheme(), $schemes, true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentication mechanisms visible for $visibleFor
|
||||
*
|
||||
* @param int $visibleFor
|
||||
* @return AuthMechanism[]
|
||||
*/
|
||||
public function getAuthMechanismsVisibleFor($visibleFor) {
|
||||
return array_filter($this->getAuthMechanisms(), function($authMechanism) use ($visibleFor) {
|
||||
return $authMechanism->isVisibleFor($visibleFor);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentication mechanisms allowed to be visible for $visibleFor
|
||||
*
|
||||
* @param int $visibleFor
|
||||
* @return AuthMechanism[]
|
||||
*/
|
||||
public function getAuthMechanismsAllowedVisibleFor($visibleFor) {
|
||||
return array_filter($this->getAuthMechanisms(), function($authMechanism) use ($visibleFor) {
|
||||
return $authMechanism->isAllowedVisibleFor($visibleFor);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $identifier
|
||||
* @return AuthMechanism|null
|
||||
*/
|
||||
public function getAuthMechanism($identifier) {
|
||||
if (isset($this->authMechanisms[$identifier])) {
|
||||
return $this->authMechanisms[$identifier];
|
||||
}
|
||||
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 &&
|
||||
!empty(array_intersect($backend->getIdentifierAliases(), $this->userMountingBackends))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an authentication mechanism if a user is allowed to use it
|
||||
*
|
||||
* @param AuthMechanism $authMechanism
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAllowedAuthMechanism(AuthMechanism $authMechanism) {
|
||||
return true; // not implemented
|
||||
}
|
||||
}
|
|
@ -92,7 +92,7 @@ class GlobalStoragesService extends StoragesService {
|
|||
$storageConfig->setBackendOptions($oldBackendOptions);
|
||||
}
|
||||
|
||||
\OC_Mount_Config::writeData(null, $mountPoints);
|
||||
$this->writeLegacyConfig($mountPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -44,6 +55,16 @@ abstract class StoragesService {
|
|||
return \OC_Mount_Config::readData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write legacy config data
|
||||
*
|
||||
* @param array $mountPoints
|
||||
*/
|
||||
protected function writeLegacyConfig(array $mountPoints) {
|
||||
// write global config
|
||||
\OC_Mount_Config::writeData(null, $mountPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy legacy storage options into the given storage config object.
|
||||
*
|
||||
|
@ -60,14 +81,31 @@ abstract class StoragesService {
|
|||
$applicable,
|
||||
$storageOptions
|
||||
) {
|
||||
$storageConfig->setBackendClass($storageOptions['class']);
|
||||
$backend = $this->backendService->getBackend($storageOptions['backend']);
|
||||
if (!$backend) {
|
||||
throw new \UnexpectedValueException('Invalid backend '.$storageOptions['backend']);
|
||||
}
|
||||
$storageConfig->setBackend($backend);
|
||||
|
||||
if (isset($storageOptions['authMechanism'])) {
|
||||
$authMechanism = $this->backendService->getAuthMechanism($storageOptions['authMechanism']);
|
||||
} else {
|
||||
$authMechanism = $backend->getLegacyAuthMechanism($storageOptions);
|
||||
$storageOptions['authMechanism'] = 'null'; // to make error handling easier
|
||||
}
|
||||
if (!$authMechanism) {
|
||||
throw new \UnexpectedValueException('Invalid authentication mechanism '.$storageOptions['authMechanism']);
|
||||
}
|
||||
$storageConfig->setAuthMechanism($authMechanism);
|
||||
|
||||
$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();
|
||||
|
@ -102,8 +140,10 @@ abstract class StoragesService {
|
|||
* - $mountPath is the mount point path (where the storage must be mounted)
|
||||
* - $storageOptions is a map of storage options:
|
||||
* - "priority": storage priority
|
||||
* - "backend": backend class name
|
||||
* - "backend": backend identifier
|
||||
* - "class": LEGACY backend class name
|
||||
* - "options": backend-specific options
|
||||
* - "authMechanism": authentication mechanism identifier
|
||||
* - "mountOptions": mount-specific options (ex: disable previews, scanner, etc)
|
||||
*/
|
||||
|
||||
|
@ -147,6 +187,13 @@ abstract class StoragesService {
|
|||
// options might be needed for the config hash
|
||||
$storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']);
|
||||
|
||||
if (!isset($storageOptions['backend'])) {
|
||||
$storageOptions['backend'] = $storageOptions['class']; // legacy compat
|
||||
}
|
||||
if (!isset($storageOptions['authMechanism'])) {
|
||||
$storageOptions['authMechanism'] = null; // ensure config hash works
|
||||
}
|
||||
|
||||
if (isset($storageOptions['id'])) {
|
||||
$configId = (int)$storageOptions['id'];
|
||||
if (isset($storages[$configId])) {
|
||||
|
@ -188,20 +235,30 @@ abstract class StoragesService {
|
|||
|
||||
// process storages with config hash, they must get a real id
|
||||
if (!empty($storagesWithConfigHash)) {
|
||||
$nextId = $this->generateNextId($storages);
|
||||
foreach ($storagesWithConfigHash as $storage) {
|
||||
$storage->setId($nextId);
|
||||
$storages[$nextId] = $storage;
|
||||
$nextId++;
|
||||
}
|
||||
|
||||
// re-save the config with the generated ids
|
||||
$this->writeConfig($storages);
|
||||
$this->setRealStorageIds($storages, $storagesWithConfigHash);
|
||||
}
|
||||
|
||||
return $storages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace config hash ID with real IDs, for migrating legacy storages
|
||||
*
|
||||
* @param StorageConfig[] $storages Storages with real IDs
|
||||
* @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
|
||||
*/
|
||||
protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
|
||||
$nextId = $this->generateNextId($storages);
|
||||
foreach ($storagesWithConfigHash as $storage) {
|
||||
$storage->setId($nextId);
|
||||
$storages[$nextId] = $storage;
|
||||
$nextId++;
|
||||
}
|
||||
|
||||
// re-save the config with the generated ids
|
||||
$this->writeConfig($storages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add mount point into the messy mount point structure
|
||||
*
|
||||
|
@ -222,7 +279,9 @@ abstract class StoragesService {
|
|||
|
||||
$options = [
|
||||
'id' => $storageConfig->getId(),
|
||||
'class' => $storageConfig->getBackendClass(),
|
||||
'backend' => $storageConfig->getBackend()->getIdentifier(),
|
||||
//'class' => $storageConfig->getBackend()->getClass(),
|
||||
'authMechanism' => $storageConfig->getAuthMechanism()->getIdentifier(),
|
||||
'options' => $storageConfig->getBackendOptions(),
|
||||
];
|
||||
|
||||
|
@ -296,6 +355,59 @@ abstract class StoragesService {
|
|||
return $newStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a storage from its parameters
|
||||
*
|
||||
* @param string $mountPoint storage mount point
|
||||
* @param string $backendIdentifier backend identifier
|
||||
* @param string $authMechanismIdentifier authentication mechanism identifier
|
||||
* @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,
|
||||
$backendIdentifier,
|
||||
$authMechanismIdentifier,
|
||||
$backendOptions,
|
||||
$mountOptions = null,
|
||||
$applicableUsers = null,
|
||||
$applicableGroups = null,
|
||||
$priority = null
|
||||
) {
|
||||
$backend = $this->backendService->getBackend($backendIdentifier);
|
||||
if (!$backend) {
|
||||
throw new \InvalidArgumentException('Unable to get backend for '.$backendIdentifier);
|
||||
}
|
||||
$authMechanism = $this->backendService->getAuthMechanism($authMechanismIdentifier);
|
||||
if (!$authMechanism) {
|
||||
throw new \InvalidArgumentException('Unable to get authentication mechanism for '.$authMechanismIdentifier);
|
||||
}
|
||||
$newStorage = new StorageConfig();
|
||||
$newStorage->setMountPoint($mountPoint);
|
||||
$newStorage->setBackend($backend);
|
||||
$newStorage->setAuthMechanism($authMechanism);
|
||||
$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
|
||||
*
|
||||
|
|
107
apps/files_external/service/userglobalstoragesservice.php
Normal file
107
apps/files_external/service/userglobalstoragesservice.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?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\Service;
|
||||
|
||||
use \OCA\Files_external\Service\GlobalStoragesService;
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
use \OCP\IUserSession;
|
||||
use \OCP\IGroupManager;
|
||||
use \OCA\Files_External\Service\UserTrait;
|
||||
|
||||
/**
|
||||
* Service class to read global storages applicable to the user
|
||||
* Read-only access available, attempting to write will throw DomainException
|
||||
*/
|
||||
class UserGlobalStoragesService extends GlobalStoragesService {
|
||||
|
||||
use UserTrait;
|
||||
|
||||
/** @var IGroupManager */
|
||||
protected $groupManager;
|
||||
|
||||
/**
|
||||
* @param BackendService $backendService
|
||||
* @param IUserSession $userSession
|
||||
* @param IGroupManager $groupManager
|
||||
*/
|
||||
public function __construct(
|
||||
BackendService $backendService,
|
||||
IUserSession $userSession,
|
||||
IGroupManager $groupManager
|
||||
) {
|
||||
parent::__construct($backendService);
|
||||
$this->userSession = $userSession;
|
||||
$this->groupManager = $groupManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace config hash ID with real IDs, for migrating legacy storages
|
||||
*
|
||||
* @param StorageConfig[] $storages Storages with real IDs
|
||||
* @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
|
||||
*/
|
||||
protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
|
||||
// as a read-only view, storage IDs don't need to be real
|
||||
foreach ($storagesWithConfigHash as $storage) {
|
||||
$storages[$storage->getId()] = $storage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read legacy config data
|
||||
*
|
||||
* @return array list of mount configs
|
||||
*/
|
||||
protected function readLegacyConfig() {
|
||||
// read global config
|
||||
$data = parent::readLegacyConfig();
|
||||
$userId = $this->getUser()->getUID();
|
||||
|
||||
if (isset($data[\OC_Mount_Config::MOUNT_TYPE_USER])) {
|
||||
$data[\OC_Mount_Config::MOUNT_TYPE_USER] = array_filter(
|
||||
$data[\OC_Mount_Config::MOUNT_TYPE_USER], function($key) use ($userId) {
|
||||
return (strtolower($key) === strtolower($userId) || $key === 'all');
|
||||
}, ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($data[\OC_Mount_Config::MOUNT_TYPE_GROUP])) {
|
||||
$data[\OC_Mount_Config::MOUNT_TYPE_GROUP] = array_filter(
|
||||
$data[\OC_Mount_Config::MOUNT_TYPE_GROUP], function($key) use ($userId) {
|
||||
return ($this->groupManager->isInGroup($userId, $key));
|
||||
}, ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write legacy config data
|
||||
*
|
||||
* @param array $mountPoints
|
||||
*/
|
||||
protected function writeLegacyConfig(array $mountPoints) {
|
||||
throw new \DomainException('UserGlobalStoragesService writing disallowed');
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,8 @@ use \OC\Files\Filesystem;
|
|||
|
||||
use \OCA\Files_external\Lib\StorageConfig;
|
||||
use \OCA\Files_external\NotFoundException;
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
use \OCA\Files_External\Service\UserTrait;
|
||||
|
||||
/**
|
||||
* Service class to manage user external storages
|
||||
|
@ -33,22 +35,20 @@ use \OCA\Files_external\NotFoundException;
|
|||
*/
|
||||
class UserStoragesService extends StoragesService {
|
||||
|
||||
/**
|
||||
* User session
|
||||
*
|
||||
* @var IUserSession
|
||||
*/
|
||||
private $userSession;
|
||||
use UserTrait;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,17 +58,28 @@ class UserStoragesService extends StoragesService {
|
|||
*/
|
||||
protected function readLegacyConfig() {
|
||||
// read user config
|
||||
$user = $this->userSession->getUser()->getUID();
|
||||
$user = $this->getUser()->getUID();
|
||||
return \OC_Mount_Config::readData($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write legacy config data
|
||||
*
|
||||
* @param array $mountPoints
|
||||
*/
|
||||
protected function writeLegacyConfig(array $mountPoints) {
|
||||
// write user config
|
||||
$user = $this->getUser()->getUID();
|
||||
\OC_Mount_Config::writeData($user, $mountPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the external storages config
|
||||
*
|
||||
* @return array map of storage id to storage config
|
||||
*/
|
||||
protected function readConfig() {
|
||||
$user = $this->userSession->getUser()->getUID();
|
||||
$user = $this->getUser()->getUID();
|
||||
// TODO: in the future don't rely on the global config reading code
|
||||
$storages = parent::readConfig();
|
||||
|
||||
|
@ -95,7 +106,7 @@ class UserStoragesService extends StoragesService {
|
|||
* @param array $storages map of storage id to storage config
|
||||
*/
|
||||
public function writeConfig($storages) {
|
||||
$user = $this->userSession->getUser()->getUID();
|
||||
$user = $this->getUser()->getUID();
|
||||
|
||||
// let the horror begin
|
||||
$mountPoints = [];
|
||||
|
@ -123,7 +134,7 @@ class UserStoragesService extends StoragesService {
|
|||
$storageConfig->setBackendOptions($oldBackendOptions);
|
||||
}
|
||||
|
||||
\OC_Mount_Config::writeData($user, $mountPoints);
|
||||
$this->writeLegacyConfig($mountPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,7 +145,7 @@ class UserStoragesService extends StoragesService {
|
|||
* @param string $signal signal to trigger
|
||||
*/
|
||||
protected function triggerHooks(StorageConfig $storage, $signal) {
|
||||
$user = $this->userSession->getUser()->getUID();
|
||||
$user = $this->getUser()->getUID();
|
||||
|
||||
// trigger hook for the current user
|
||||
$this->triggerApplicableHooks(
|
||||
|
|
74
apps/files_external/service/usertrait.php
Normal file
74
apps/files_external/service/usertrait.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?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\Service;
|
||||
|
||||
use \OCP\IUserSession;
|
||||
use \OCP\IUser;
|
||||
|
||||
/**
|
||||
* Trait for getting user information in a service
|
||||
*/
|
||||
trait UserTrait {
|
||||
|
||||
/** @var IUserSession */
|
||||
protected $userSession;
|
||||
|
||||
/**
|
||||
* User override
|
||||
*
|
||||
* @var IUser|null
|
||||
*/
|
||||
private $user = null;
|
||||
|
||||
/**
|
||||
* @return IUser|null
|
||||
*/
|
||||
protected function getUser() {
|
||||
if ($this->user) {
|
||||
return $this->user;
|
||||
}
|
||||
return $this->userSession->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the user from the session
|
||||
* Unset with ->resetUser() when finished!
|
||||
*
|
||||
* @param IUser
|
||||
* @return self
|
||||
*/
|
||||
public function setUser(IUser $user) {
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the user override
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function resetUser() {
|
||||
$this->user = null;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,54 +26,41 @@
|
|||
*
|
||||
*/
|
||||
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
|
||||
OC_Util::checkAdminUser();
|
||||
|
||||
// we must use the same container
|
||||
$appContainer = \OC_Mount_Config::$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),
|
||||
);
|
||||
$backends = $backendService->getBackendsVisibleFor(BackendService::VISIBILITY_ADMIN);
|
||||
$authMechanisms = $backendService->getAuthMechanismsVisibleFor(BackendService::VISIBILITY_ADMIN);
|
||||
foreach ($backends as $backend) {
|
||||
if ($backend->getCustomJs()) {
|
||||
\OCP\Util::addScript('files_external', $backend->getCustomJs());
|
||||
}
|
||||
}
|
||||
|
||||
$mounts = OC_Mount_Config::getSystemMountPoints();
|
||||
$hasId = true;
|
||||
foreach ($mounts as $mount) {
|
||||
if (!isset($mount['id'])) {
|
||||
// some mount points are missing ids
|
||||
$hasId = false;
|
||||
break;
|
||||
foreach ($authMechanisms as $authMechanism) {
|
||||
if ($authMechanism->getCustomJs()) {
|
||||
\OCP\Util::addScript('files_external', $authMechanism->getCustomJs());
|
||||
}
|
||||
}
|
||||
|
||||
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('storages', $globalStoragesService->getAllStorages());
|
||||
$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('authMechanisms', $authMechanisms);
|
||||
$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();
|
||||
|
|
|
@ -1,3 +1,58 @@
|
|||
<?php
|
||||
use \OCA\Files_External\Lib\Backend\Backend;
|
||||
use \OCA\Files_External\Lib\DefinitionParameter;
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
|
||||
function writeParameterInput($parameter, $options, $classes = []) {
|
||||
$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: ?>
|
||||
<?php if ($is_optional) { $classes[] = 'optional'; } ?>
|
||||
<input type="password"
|
||||
<?php if (!empty($classes)): ?> class="<?php p(implode(' ', $classes)); ?>"<?php endif; ?>
|
||||
data-parameter="<?php p($parameter->getName()); ?>"
|
||||
value="<?php p($value); ?>"
|
||||
placeholder="<?php p($placeholder); ?>"
|
||||
/>
|
||||
<?php
|
||||
break;
|
||||
case DefinitionParameter::VALUE_BOOLEAN: ?>
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
<?php if (!empty($classes)): ?> class="<?php p(implode(' ', $classes)); ?>"<?php endif; ?>
|
||||
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"
|
||||
<?php if (!empty($classes)): ?> class="<?php p(implode(' ', $classes)); ?>"<?php endif; ?>
|
||||
data-parameter="<?php p($parameter->getName()); ?>"
|
||||
value="<?php p($value); ?>"
|
||||
/>
|
||||
<?php
|
||||
break;
|
||||
default: ?>
|
||||
<?php if ($is_optional) { $classes[] = 'optional'; } ?>
|
||||
<input type="text"
|
||||
<?php if (!empty($classes)): ?> class="<?php p(implode(' ', $classes)); ?>"<?php endif; ?>
|
||||
data-parameter="<?php p($parameter->getName()); ?>"
|
||||
value="<?php p($value); ?>"
|
||||
placeholder="<?php p($placeholder); ?>"
|
||||
/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
<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'].''); ?>
|
||||
|
@ -7,6 +62,7 @@
|
|||
<th></th>
|
||||
<th><?php p($l->t('Folder name')); ?></th>
|
||||
<th><?php p($l->t('External storage')); ?></th>
|
||||
<th><?php p($l->t('Authentication')); ?></th>
|
||||
<th><?php p($l->t('Configuration')); ?></th>
|
||||
<?php if ($_['isAdminPage']) print_unescaped('<th>'.$l->t('Available for').'</th>'); ?>
|
||||
<th> </th>
|
||||
|
@ -14,103 +70,120 @@
|
|||
</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()->getIdentifier()); ?>" 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])): ?>
|
||||
<?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; ?>
|
||||
<td class="backend" data-class="<?php p($storage->getBackend()->getIdentifier()); ?>"><?php p($storage->getBackend()->getText()); ?>
|
||||
</td>
|
||||
<td class="authentication">
|
||||
<select class="selectAuthMechanism">
|
||||
<?php
|
||||
$authSchemes = $storage->getBackend()->getAuthSchemes();
|
||||
$authMechanisms = array_filter($_['authMechanisms'], function($mech) use ($authSchemes) {
|
||||
return isset($authSchemes[$mech->getScheme()]);
|
||||
});
|
||||
?>
|
||||
<?php foreach ($authMechanisms as $mech): ?>
|
||||
<option value="<?php p($mech->getIdentifier()); ?>" data-scheme="<?php p($mech->getScheme());?>"
|
||||
<?php if ($mech->getIdentifier() === $storage->getAuthMechanism()->getIdentifier()): ?>selected<?php endif; ?>
|
||||
><?php p($mech->getText()); ?></option>
|
||||
<?php endforeach; ?>
|
||||
<?php if (isset($_['backends'][$mount['class']]['custom'])): ?>
|
||||
<?php OCP\Util::addScript('files_external', $_['backends'][$mount['class']]['custom']); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</td>
|
||||
<td class="configuration">
|
||||
<?php
|
||||
$options = $storage->getBackendOptions();
|
||||
foreach ($storage->getBackend()->getParameters() as $parameter) {
|
||||
writeParameterInput($parameter, $options);
|
||||
}
|
||||
foreach ($storage->getAuthMechanism()->getParameters() as $parameter) {
|
||||
writeParameterInput($parameter, $options, ['auth-param']);
|
||||
}
|
||||
?>
|
||||
</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->getIdentifier()); ?>"><?php p($backend->getText()); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
<td class="authentication" data-mechanisms='<?php p(json_encode($_['authMechanisms'])); ?>'></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 +196,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->getIdentifier()); ?>" <?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>
|
||||
|
|
80
apps/files_external/tests/auth/authmechanismtest.php
Normal file
80
apps/files_external/tests/auth/authmechanismtest.php
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?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\Tests\Auth;
|
||||
|
||||
class AuthMechanismTest extends \Test\TestCase {
|
||||
|
||||
public function testJsonSerialization() {
|
||||
$mechanism = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\AuthMechanism')
|
||||
->setMethods(['jsonSerializeDefinition'])
|
||||
->getMock();
|
||||
$mechanism->expects($this->once())
|
||||
->method('jsonSerializeDefinition')
|
||||
->willReturn(['foo' => 'bar']);
|
||||
|
||||
$mechanism->setScheme('scheme');
|
||||
|
||||
$json = $mechanism->jsonSerialize();
|
||||
$this->assertEquals('bar', $json['foo']);
|
||||
$this->assertEquals('scheme', $json['scheme']);
|
||||
}
|
||||
|
||||
public function validateStorageProvider() {
|
||||
return [
|
||||
[true, 'scheme', true],
|
||||
[false, 'scheme', false],
|
||||
[true, 'foobar', true],
|
||||
[false, 'barfoo', true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validateStorageProvider
|
||||
*/
|
||||
public function testValidateStorage($expectedSuccess, $scheme, $definitionSuccess) {
|
||||
$mechanism = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\AuthMechanism')
|
||||
->setMethods(['validateStorageDefinition'])
|
||||
->getMock();
|
||||
$mechanism->expects($this->atMost(1))
|
||||
->method('validateStorageDefinition')
|
||||
->willReturn($definitionSuccess);
|
||||
|
||||
$mechanism->setScheme($scheme);
|
||||
|
||||
$backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$backend->expects($this->once())
|
||||
->method('getAuthSchemes')
|
||||
->willReturn(['scheme' => true, 'foobar' => true]);
|
||||
|
||||
$storageConfig = $this->getMockBuilder('\OCA\Files_External\Lib\StorageConfig')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$storageConfig->expects($this->once())
|
||||
->method('getBackend')
|
||||
->willReturn($backend);
|
||||
|
||||
$this->assertEquals($expectedSuccess, $mechanism->validateStorage($storageConfig));
|
||||
}
|
||||
|
||||
}
|
89
apps/files_external/tests/backend/backendtest.php
Normal file
89
apps/files_external/tests/backend/backendtest.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?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\Tests\Backend;
|
||||
|
||||
use \OCA\Files_External\Lib\Backend\Backend;
|
||||
|
||||
class BackendTest extends \Test\TestCase {
|
||||
|
||||
public function testJsonSerialization() {
|
||||
$backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
|
||||
->setMethods(['jsonSerializeDefinition'])
|
||||
->getMock();
|
||||
$backend->expects($this->once())
|
||||
->method('jsonSerializeDefinition')
|
||||
->willReturn(['foo' => 'bar', 'name' => 'abc']);
|
||||
|
||||
$backend->setPriority(57);
|
||||
$backend->addAuthScheme('foopass');
|
||||
$backend->addAuthScheme('barauth');
|
||||
|
||||
$json = $backend->jsonSerialize();
|
||||
$this->assertEquals('bar', $json['foo']);
|
||||
$this->assertEquals('abc', $json['name']);
|
||||
$this->assertEquals($json['name'], $json['backend']);
|
||||
$this->assertEquals(57, $json['priority']);
|
||||
|
||||
$this->assertContains('foopass', $json['authSchemes']);
|
||||
$this->assertContains('barauth', $json['authSchemes']);
|
||||
}
|
||||
|
||||
public function validateStorageProvider() {
|
||||
return [
|
||||
[true, true],
|
||||
[false, false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validateStorageProvider
|
||||
*/
|
||||
public function testValidateStorage($expectedSuccess, $definitionSuccess) {
|
||||
$backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
|
||||
->setMethods(['validateStorageDefinition'])
|
||||
->getMock();
|
||||
$backend->expects($this->atMost(1))
|
||||
->method('validateStorageDefinition')
|
||||
->willReturn($definitionSuccess);
|
||||
|
||||
$storageConfig = $this->getMockBuilder('\OCA\Files_External\Lib\StorageConfig')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->assertEquals($expectedSuccess, $backend->validateStorage($storageConfig));
|
||||
}
|
||||
|
||||
public function testLegacyAuthMechanismCallback() {
|
||||
$backend = new Backend();
|
||||
$backend->setLegacyAuthMechanismCallback(function(array $params) {
|
||||
if (isset($params['ping'])) {
|
||||
return 'pong';
|
||||
}
|
||||
return 'foobar';
|
||||
});
|
||||
|
||||
$this->assertEquals('pong', $backend->getLegacyAuthMechanism(['ping' => true]));
|
||||
$this->assertEquals('foobar', $backend->getLegacyAuthMechanism(['other' => true]));
|
||||
$this->assertEquals('foobar', $backend->getLegacyAuthMechanism());
|
||||
}
|
||||
|
||||
}
|
81
apps/files_external/tests/backend/legacybackendtest.php
Normal file
81
apps/files_external/tests/backend/legacybackendtest.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?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\Tests\Backend;
|
||||
|
||||
use \OCA\Files_External\Lib\Backend\LegacyBackend;
|
||||
use \OCA\Files_External\Lib\DefinitionParameter;
|
||||
|
||||
class LegacyBackendTest extends \Test\TestCase {
|
||||
|
||||
public function testConstructor() {
|
||||
$auth = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\Builtin')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$class = '\OC\Files\Storage\SMB';
|
||||
$definition = [
|
||||
'configuration' => [
|
||||
'textfield' => 'Text field',
|
||||
'passwordfield' => '*Password field',
|
||||
'checkbox' => '!Checkbox',
|
||||
'hiddenfield' => '#Hidden field',
|
||||
'optionaltext' => '&Optional text field',
|
||||
'optionalpassword' => '&*Optional password field',
|
||||
],
|
||||
'backend' => 'Backend text',
|
||||
'priority' => 123,
|
||||
'custom' => 'foo/bar.js',
|
||||
'has_dependencies' => true,
|
||||
];
|
||||
|
||||
$backend = new LegacyBackend($class, $definition, $auth);
|
||||
|
||||
$this->assertEquals('\OC\Files\Storage\SMB', $backend->getStorageClass());
|
||||
$this->assertEquals('Backend text', $backend->getText());
|
||||
$this->assertEquals(123, $backend->getPriority());
|
||||
$this->assertEquals('foo/bar.js', $backend->getCustomJs());
|
||||
$this->assertEquals(true, $backend->hasDependencies());
|
||||
$this->assertArrayHasKey('builtin', $backend->getAuthSchemes());
|
||||
$this->assertEquals($auth, $backend->getLegacyAuthMechanism());
|
||||
|
||||
$parameters = $backend->getParameters();
|
||||
$this->assertEquals('Text field', $parameters['textfield']->getText());
|
||||
$this->assertEquals(DefinitionParameter::VALUE_TEXT, $parameters['textfield']->getType());
|
||||
$this->assertEquals(DefinitionParameter::FLAG_NONE, $parameters['textfield']->getFlags());
|
||||
$this->assertEquals('Password field', $parameters['passwordfield']->getText());
|
||||
$this->assertEquals(DefinitionParameter::VALUE_PASSWORD, $parameters['passwordfield']->getType());
|
||||
$this->assertEquals(DefinitionParameter::FLAG_NONE, $parameters['passwordfield']->getFlags());
|
||||
$this->assertEquals('Checkbox', $parameters['checkbox']->getText());
|
||||
$this->assertEquals(DefinitionParameter::VALUE_BOOLEAN, $parameters['checkbox']->getType());
|
||||
$this->assertEquals(DefinitionParameter::FLAG_NONE, $parameters['checkbox']->getFlags());
|
||||
$this->assertEquals('Hidden field', $parameters['hiddenfield']->getText());
|
||||
$this->assertEquals(DefinitionParameter::VALUE_HIDDEN, $parameters['hiddenfield']->getType());
|
||||
$this->assertEquals(DefinitionParameter::FLAG_NONE, $parameters['hiddenfield']->getFlags());
|
||||
$this->assertEquals('Optional text field', $parameters['optionaltext']->getText());
|
||||
$this->assertEquals(DefinitionParameter::VALUE_TEXT, $parameters['optionaltext']->getType());
|
||||
$this->assertEquals(DefinitionParameter::FLAG_OPTIONAL, $parameters['optionaltext']->getFlags());
|
||||
$this->assertEquals('Optional password field', $parameters['optionalpassword']->getText());
|
||||
$this->assertEquals(DefinitionParameter::VALUE_PASSWORD, $parameters['optionalpassword']->getType());
|
||||
$this->assertEquals(DefinitionParameter::FLAG_OPTIONAL, $parameters['optionalpassword']->getFlags());
|
||||
}
|
||||
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
* @author Robin McCorkell <rmccorkell@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
|
@ -47,10 +48,48 @@ 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('getIdentifier')
|
||||
->willReturn('identifier:'.$class);
|
||||
return $backend;
|
||||
}
|
||||
|
||||
protected function getAuthMechMock($scheme = 'null', $class = '\OCA\Files_External\Lib\Auth\NullMechanism') {
|
||||
$authMech = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\AuthMechanism')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$authMech->method('getScheme')
|
||||
->willReturn($scheme);
|
||||
$authMech->method('getIdentifier')
|
||||
->willReturn('identifier:'.$class);
|
||||
|
||||
return $authMech;
|
||||
}
|
||||
|
||||
public function testAddStorage() {
|
||||
$authMech = $this->getAuthMechMock();
|
||||
$authMech->method('validateStorage')
|
||||
->willReturn(true);
|
||||
$backend = $this->getBackendMock();
|
||||
$backend->method('validateStorage')
|
||||
->willReturn(true);
|
||||
$backend->method('isVisibleFor')
|
||||
->willReturn(true);
|
||||
|
||||
$storageConfig = new StorageConfig(1);
|
||||
$storageConfig->setMountPoint('mount');
|
||||
$storageConfig->setBackend($backend);
|
||||
$storageConfig->setAuthMechanism($authMech);
|
||||
$storageConfig->setBackendOptions([]);
|
||||
|
||||
$this->service->expects($this->once())
|
||||
->method('createStorage')
|
||||
->will($this->returnValue($storageConfig));
|
||||
$this->service->expects($this->once())
|
||||
->method('addStorage')
|
||||
->will($this->returnValue($storageConfig));
|
||||
|
@ -58,6 +97,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
$response = $this->controller->create(
|
||||
'mount',
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -66,14 +106,29 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
);
|
||||
|
||||
$data = $response->getData();
|
||||
$this->assertEquals($storageConfig, $data);
|
||||
$this->assertEquals(Http::STATUS_CREATED, $response->getStatus());
|
||||
$this->assertEquals($storageConfig, $data);
|
||||
}
|
||||
|
||||
public function testUpdateStorage() {
|
||||
$authMech = $this->getAuthMechMock();
|
||||
$authMech->method('validateStorage')
|
||||
->willReturn(true);
|
||||
$backend = $this->getBackendMock();
|
||||
$backend->method('validateStorage')
|
||||
->willReturn(true);
|
||||
$backend->method('isVisibleFor')
|
||||
->willReturn(true);
|
||||
|
||||
$storageConfig = new StorageConfig(1);
|
||||
$storageConfig->setMountPoint('mount');
|
||||
$storageConfig->setBackend($backend);
|
||||
$storageConfig->setAuthMechanism($authMech);
|
||||
$storageConfig->setBackendOptions([]);
|
||||
|
||||
$this->service->expects($this->once())
|
||||
->method('createStorage')
|
||||
->will($this->returnValue($storageConfig));
|
||||
$this->service->expects($this->once())
|
||||
->method('updateStorage')
|
||||
->will($this->returnValue($storageConfig));
|
||||
|
@ -82,6 +137,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
1,
|
||||
'mount',
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -90,8 +146,8 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
);
|
||||
|
||||
$data = $response->getData();
|
||||
$this->assertEquals($storageConfig, $data);
|
||||
$this->assertEquals(Http::STATUS_OK, $response->getStatus());
|
||||
$this->assertEquals($storageConfig, $data);
|
||||
}
|
||||
|
||||
function mountPointNamesProvider() {
|
||||
|
@ -106,6 +162,15 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
* @dataProvider mountPointNamesProvider
|
||||
*/
|
||||
public function testAddOrUpdateStorageInvalidMountPoint($mountPoint) {
|
||||
$storageConfig = new StorageConfig(1);
|
||||
$storageConfig->setMountPoint($mountPoint);
|
||||
$storageConfig->setBackend($this->getBackendMock());
|
||||
$storageConfig->setAuthMechanism($this->getAuthMechMock());
|
||||
$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())
|
||||
|
@ -114,6 +179,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
$response = $this->controller->create(
|
||||
$mountPoint,
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -127,6 +193,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
1,
|
||||
$mountPoint,
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -138,6 +205,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())
|
||||
|
@ -146,6 +216,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
$response = $this->controller->create(
|
||||
'mount',
|
||||
'\OC\Files\Storage\InvalidStorage',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -159,6 +230,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
1,
|
||||
'mount',
|
||||
'\OC\Files\Storage\InvalidStorage',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -170,6 +242,24 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function testUpdateStorageNonExisting() {
|
||||
$authMech = $this->getAuthMechMock();
|
||||
$authMech->method('validateStorage')
|
||||
->willReturn(true);
|
||||
$backend = $this->getBackendMock();
|
||||
$backend->method('validateStorage')
|
||||
->willReturn(true);
|
||||
$backend->method('isVisibleFor')
|
||||
->willReturn(true);
|
||||
|
||||
$storageConfig = new StorageConfig(255);
|
||||
$storageConfig->setMountPoint('mount');
|
||||
$storageConfig->setBackend($backend);
|
||||
$storageConfig->setAuthMechanism($authMech);
|
||||
$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()));
|
||||
|
@ -178,6 +268,7 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
255,
|
||||
'mount',
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -206,9 +297,12 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function testGetStorage() {
|
||||
$backend = $this->getBackendMock();
|
||||
$authMech = $this->getAuthMechMock();
|
||||
$storageConfig = new StorageConfig(1);
|
||||
$storageConfig->setMountPoint('test');
|
||||
$storageConfig->setBackendClass('\OC\Files\Storage\SMB');
|
||||
$storageConfig->setBackend($backend);
|
||||
$storageConfig->setAuthMechanism($authMech);
|
||||
$storageConfig->setBackendOptions(['user' => 'test', 'password', 'password123']);
|
||||
$storageConfig->setMountOptions(['priority' => false]);
|
||||
|
||||
|
@ -221,4 +315,66 @@ abstract class StoragesControllerTest extends \Test\TestCase {
|
|||
$this->assertEquals(Http::STATUS_OK, $response->getStatus());
|
||||
$this->assertEquals($storageConfig, $response->getData());
|
||||
}
|
||||
|
||||
public function validateStorageProvider() {
|
||||
return [
|
||||
[true, true, true],
|
||||
[false, true, false],
|
||||
[true, false, false],
|
||||
[false, false, false]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validateStorageProvider
|
||||
*/
|
||||
public function testValidateStorage($backendValidate, $authMechValidate, $expectSuccess) {
|
||||
$backend = $this->getBackendMock();
|
||||
$backend->method('validateStorage')
|
||||
->willReturn($backendValidate);
|
||||
$backend->method('isVisibleFor')
|
||||
->willReturn(true);
|
||||
|
||||
$authMech = $this->getAuthMechMock();
|
||||
$authMech->method('validateStorage')
|
||||
->will($this->returnValue($authMechValidate));
|
||||
|
||||
$storageConfig = new StorageConfig();
|
||||
$storageConfig->setMountPoint('mount');
|
||||
$storageConfig->setBackend($backend);
|
||||
$storageConfig->setAuthMechanism($authMech);
|
||||
$storageConfig->setBackendOptions([]);
|
||||
|
||||
$this->service->expects($this->once())
|
||||
->method('createStorage')
|
||||
->will($this->returnValue($storageConfig));
|
||||
|
||||
if ($expectSuccess) {
|
||||
$this->service->expects($this->once())
|
||||
->method('addStorage')
|
||||
->with($storageConfig)
|
||||
->will($this->returnValue($storageConfig));
|
||||
} else {
|
||||
$this->service->expects($this->never())
|
||||
->method('addStorage');
|
||||
}
|
||||
|
||||
$response = $this->controller->create(
|
||||
'mount',
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\OCA\Files_External\Lib\Auth\NullMechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
null
|
||||
);
|
||||
|
||||
if ($expectSuccess) {
|
||||
$this->assertEquals(Http::STATUS_CREATED, $response->getStatus());
|
||||
} else {
|
||||
$this->assertEquals(Http::STATUS_UNPROCESSABLE_ENTITY, $response->getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,24 @@ 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);
|
||||
$authMech = $this->getAuthMechMock();
|
||||
|
||||
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->setAuthMechanism($authMech);
|
||||
$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 +71,8 @@ class UserStoragesControllerTest extends StoragesControllerTest {
|
|||
|
||||
$response = $this->controller->create(
|
||||
'mount',
|
||||
$backendClass,
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\Auth\Mechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
@ -99,7 +85,8 @@ class UserStoragesControllerTest extends StoragesControllerTest {
|
|||
$response = $this->controller->update(
|
||||
1,
|
||||
'mount',
|
||||
$backendClass,
|
||||
'\OC\Files\Storage\SMB',
|
||||
'\Auth\Mechanism',
|
||||
array(),
|
||||
[],
|
||||
[],
|
||||
|
|
70
apps/files_external/tests/definitionparameterttest.php
Normal file
70
apps/files_external/tests/definitionparameterttest.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?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\Tests;
|
||||
|
||||
use \OCA\Files_External\Lib\DefinitionParameter as Param;
|
||||
|
||||
class DefinitionParameterTest extends \Test\TestCase {
|
||||
|
||||
public function testJsonSerialization() {
|
||||
$param = new Param('foo', 'bar');
|
||||
$this->assertEquals('bar', $param->jsonSerialize());
|
||||
|
||||
$param->setType(Param::VALUE_BOOLEAN);
|
||||
$this->assertEquals('!bar', $param->jsonSerialize());
|
||||
|
||||
$param->setType(Param::VALUE_PASSWORD);
|
||||
$param->setFlag(Param::FLAG_OPTIONAL);
|
||||
$this->assertEquals('&*bar', $param->jsonSerialize());
|
||||
|
||||
$param->setType(Param::VALUE_HIDDEN);
|
||||
$param->setFlags(Param::FLAG_NONE);
|
||||
$this->assertEquals('#bar', $param->jsonSerialize());
|
||||
}
|
||||
|
||||
public function validateValueProvider() {
|
||||
return [
|
||||
[Param::VALUE_TEXT, Param::FLAG_NONE, 'abc', true],
|
||||
[Param::VALUE_TEXT, Param::FLAG_NONE, '', false],
|
||||
[Param::VALUE_TEXT, Param::FLAG_OPTIONAL, '', true],
|
||||
|
||||
[Param::VALUE_BOOLEAN, Param::FLAG_NONE, false, true],
|
||||
[Param::VALUE_BOOLEAN, Param::FLAG_NONE, 123, false],
|
||||
|
||||
[Param::VALUE_PASSWORD, Param::FLAG_NONE, 'foobar', true],
|
||||
[Param::VALUE_PASSWORD, Param::FLAG_NONE, '', false],
|
||||
|
||||
[Param::VALUE_HIDDEN, Param::FLAG_NONE, '', false]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validateValueProvider
|
||||
*/
|
||||
public function testValidateValue($type, $flags, $value, $success) {
|
||||
$param = new Param('foo', 'bar');
|
||||
$param->setType($type);
|
||||
$param->setFlags($flags);
|
||||
|
||||
$this->assertEquals($success, $param->validateValue($value));
|
||||
}
|
||||
}
|
45
apps/files_external/tests/dependencytraittest.php
Normal file
45
apps/files_external/tests/dependencytraittest.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?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\Tests;
|
||||
|
||||
use \OCA\Files_External\Lib\MissingDependency;
|
||||
|
||||
class DependencyTraitTest extends \Test\TestCase {
|
||||
|
||||
public function testCheckDependencies() {
|
||||
$trait = $this->getMockForTrait('\OCA\Files_External\Lib\DependencyTrait');
|
||||
$trait->setDependencyCheck(function() {
|
||||
return [
|
||||
(new MissingDependency('dependency'))->setMessage('missing dependency'),
|
||||
(new MissingDependency('program'))->setMessage('cannot find program'),
|
||||
];
|
||||
});
|
||||
|
||||
$dependencies = $trait->checkDependencies();
|
||||
$this->assertCount(2, $dependencies);
|
||||
$this->assertEquals('dependency', $dependencies[0]->getDependency());
|
||||
$this->assertEquals('missing dependency', $dependencies[0]->getMessage());
|
||||
$this->assertEquals('program', $dependencies[1]->getDependency());
|
||||
$this->assertEquals('cannot find program', $dependencies[1]->getMessage());
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
83
apps/files_external/tests/frontenddefinitiontraittest.php
Normal file
83
apps/files_external/tests/frontenddefinitiontraittest.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?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\Tests;
|
||||
|
||||
class FrontendDefinitionTraitTest extends \Test\TestCase {
|
||||
|
||||
public function testJsonSerialization() {
|
||||
$param = $this->getMockBuilder('\OCA\Files_External\Lib\DefinitionParameter')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$param->method('getName')->willReturn('foo');
|
||||
|
||||
$trait = $this->getMockForTrait('\OCA\Files_External\Lib\FrontendDefinitionTrait');
|
||||
$trait->setText('test');
|
||||
$trait->addParameters([$param]);
|
||||
$trait->setCustomJs('foo/bar.js');
|
||||
|
||||
$json = $trait->jsonSerializeDefinition();
|
||||
|
||||
$this->assertEquals('test', $json['name']);
|
||||
$this->assertEquals('foo/bar.js', $json['custom']);
|
||||
|
||||
$configuration = $json['configuration'];
|
||||
$this->assertArrayHasKey('foo', $configuration);
|
||||
}
|
||||
|
||||
public function validateStorageProvider() {
|
||||
return [
|
||||
[true, ['foo' => true, 'bar' => true, 'baz' => true]],
|
||||
[false, ['foo' => true, 'bar' => false]]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validateStorageProvider
|
||||
*/
|
||||
public function testValidateStorage($expectedSuccess, $params) {
|
||||
$backendParams = [];
|
||||
foreach ($params as $name => $valid) {
|
||||
$param = $this->getMockBuilder('\OCA\Files_External\Lib\DefinitionParameter')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$param->method('getName')
|
||||
->willReturn($name);
|
||||
$param->expects($this->once())
|
||||
->method('validateValue')
|
||||
->willReturn($valid);
|
||||
$backendParams[] = $param;
|
||||
}
|
||||
|
||||
$storageConfig = $this->getMockBuilder('\OCA\Files_External\Lib\StorageConfig')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$storageConfig->expects($this->once())
|
||||
->method('getBackendOptions')
|
||||
->willReturn([]);
|
||||
|
||||
$trait = $this->getMockForTrait('\OCA\Files_External\Lib\FrontendDefinitionTrait');
|
||||
$trait->setText('test');
|
||||
$trait->addParameters($backendParams);
|
||||
|
||||
$this->assertEquals($expectedSuccess, $trait->validateStorageDefinition($storageConfig));
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ describe('OCA.External.Settings tests', function() {
|
|||
'<option value="\\OC\\AnotherTestBackend">Another Test Backend</option>' +
|
||||
'</select>' +
|
||||
'</td>' +
|
||||
'<td class="authentication"></td>' +
|
||||
'<td class="configuration"></td>' +
|
||||
'<td class="applicable">' +
|
||||
'<input type="hidden" class="applicableUsers">' +
|
||||
|
@ -58,6 +59,9 @@ describe('OCA.External.Settings tests', function() {
|
|||
'field1': 'Display Name 1',
|
||||
'field2': '&Display Name 2'
|
||||
},
|
||||
'authSchemes': {
|
||||
'builtin': true,
|
||||
},
|
||||
'priority': 11
|
||||
},
|
||||
'\\OC\\AnotherTestBackend': {
|
||||
|
@ -66,10 +70,23 @@ describe('OCA.External.Settings tests', function() {
|
|||
'field1': 'Display Name 1',
|
||||
'field2': '&Display Name 2'
|
||||
},
|
||||
'authSchemes': {
|
||||
'builtin': true,
|
||||
},
|
||||
'priority': 12
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('#externalStorage #addMountPoint .authentication:first').data('mechanisms', {
|
||||
'mechanism1': {
|
||||
'name': 'Mechanism 1',
|
||||
'configuration': {
|
||||
},
|
||||
'scheme': 'builtin',
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
afterEach(function() {
|
||||
select2Stub.restore();
|
||||
|
@ -80,7 +97,7 @@ describe('OCA.External.Settings tests', function() {
|
|||
var view;
|
||||
|
||||
function selectBackend(backendName) {
|
||||
view.$el.find('.selectBackend:first').val('\\OC\\TestBackend').trigger('change');
|
||||
view.$el.find('.selectBackend:first').val(backendName).trigger('change');
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
|
@ -139,7 +156,8 @@ describe('OCA.External.Settings tests', function() {
|
|||
var request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files_external/globalstorages');
|
||||
expect(JSON.parse(request.requestBody)).toEqual({
|
||||
backendClass: '\\OC\\TestBackend',
|
||||
backend: '\\OC\\TestBackend',
|
||||
authMechanism: 'mechanism1',
|
||||
backendOptions: {
|
||||
'field1': 'test',
|
||||
'field2': ''
|
||||
|
|
File diff suppressed because it is too large
Load diff
152
apps/files_external/tests/service/backendservicetest.php
Normal file
152
apps/files_external/tests/service/backendservicetest.php
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?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\Tests\Service;
|
||||
|
||||
use \OCA\Files_External\Service\BackendService;
|
||||
|
||||
class BackendServiceTest extends \Test\TestCase {
|
||||
|
||||
/** @var \OCP\IConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var \OCP\IL10N */
|
||||
protected $l10n;
|
||||
|
||||
protected function setUp() {
|
||||
$this->config = $this->getMock('\OCP\IConfig');
|
||||
$this->l10n = $this->getMock('\OCP\IL10N');
|
||||
}
|
||||
|
||||
protected function getBackendMock($class) {
|
||||
$backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$backend->method('getIdentifier')->will($this->returnValue('identifier:'.$class));
|
||||
$backend->method('getIdentifierAliases')->will($this->returnValue(['identifier:'.$class]));
|
||||
return $backend;
|
||||
}
|
||||
|
||||
public function testRegisterBackend() {
|
||||
$service = new BackendService($this->config, $this->l10n);
|
||||
|
||||
$backend = $this->getBackendMock('\Foo\Bar');
|
||||
|
||||
$backendAlias = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$backendAlias->method('getIdentifierAliases')
|
||||
->willReturn(['identifier_real', 'identifier_alias']);
|
||||
$backendAlias->method('getIdentifier')
|
||||
->willReturn('identifier_real');
|
||||
|
||||
$service->registerBackend($backend);
|
||||
$service->registerBackend($backendAlias);
|
||||
|
||||
$this->assertEquals($backend, $service->getBackend('identifier:\Foo\Bar'));
|
||||
$this->assertEquals($backendAlias, $service->getBackend('identifier_real'));
|
||||
$this->assertEquals($backendAlias, $service->getBackend('identifier_alias'));
|
||||
|
||||
$backends = $service->getBackends();
|
||||
$this->assertCount(2, $backends);
|
||||
$this->assertArrayHasKey('identifier:\Foo\Bar', $backends);
|
||||
$this->assertArrayHasKey('identifier_real', $backends);
|
||||
$this->assertArrayNotHasKey('identifier_alias', $backends);
|
||||
}
|
||||
|
||||
public function testUserMountingBackends() {
|
||||
$this->config->expects($this->exactly(2))
|
||||
->method('getAppValue')
|
||||
->will($this->returnValueMap([
|
||||
['files_external', 'allow_user_mounting', 'yes', 'yes'],
|
||||
['files_external', 'user_mounting_backends', '', 'identifier:\User\Mount\Allowed,identifier_alias']
|
||||
]));
|
||||
|
||||
$service = new BackendService($this->config, $this->l10n);
|
||||
|
||||
$backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
|
||||
$backendAllowed->expects($this->never())
|
||||
->method('removeVisibility');
|
||||
$backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed');
|
||||
$backendNotAllowed->expects($this->once())
|
||||
->method('removeVisibility')
|
||||
->with(BackendService::VISIBILITY_PERSONAL);
|
||||
|
||||
$backendAlias = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$backendAlias->method('getIdentifierAliases')
|
||||
->willReturn(['identifier_real', 'identifier_alias']);
|
||||
$backendAlias->expects($this->never())
|
||||
->method('removeVisibility');
|
||||
|
||||
$service->registerBackend($backendAllowed);
|
||||
$service->registerBackend($backendNotAllowed);
|
||||
$service->registerBackend($backendAlias);
|
||||
}
|
||||
|
||||
public function testGetAvailableBackends() {
|
||||
$service = new BackendService($this->config, $this->l10n);
|
||||
|
||||
$backendAvailable = $this->getBackendMock('\Backend\Available');
|
||||
$backendAvailable->expects($this->once())
|
||||
->method('checkDependencies')
|
||||
->will($this->returnValue([]));
|
||||
$backendNotAvailable = $this->getBackendMock('\Backend\NotAvailable');
|
||||
$backendNotAvailable->expects($this->once())
|
||||
->method('checkDependencies')
|
||||
->will($this->returnValue([
|
||||
$this->getMockBuilder('\OCA\Files_External\Lib\MissingDependency')
|
||||
->disableOriginalConstructor()
|
||||
->getMock()
|
||||
]));
|
||||
|
||||
$service->registerBackend($backendAvailable);
|
||||
$service->registerBackend($backendNotAvailable);
|
||||
|
||||
$availableBackends = $service->getAvailableBackends();
|
||||
$this->assertArrayHasKey('identifier:\Backend\Available', $availableBackends);
|
||||
$this->assertArrayNotHasKey('identifier:\Backend\NotAvailable', $availableBackends);
|
||||
}
|
||||
|
||||
public function testGetUserBackends() {
|
||||
$service = new BackendService($this->config, $this->l10n);
|
||||
|
||||
$backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
|
||||
$backendAllowed->expects($this->once())
|
||||
->method('isVisibleFor')
|
||||
->with(BackendService::VISIBILITY_PERSONAL)
|
||||
->will($this->returnValue(true));
|
||||
$backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed');
|
||||
$backendNotAllowed->expects($this->once())
|
||||
->method('isVisibleFor')
|
||||
->with(BackendService::VISIBILITY_PERSONAL)
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$service->registerBackend($backendAllowed);
|
||||
$service->registerBackend($backendNotAllowed);
|
||||
|
||||
$userBackends = $service->getBackendsVisibleFor(BackendService::VISIBILITY_PERSONAL);
|
||||
$this->assertArrayHasKey('identifier:\User\Mount\Allowed', $userBackends);
|
||||
$this->assertArrayNotHasKey('identifier:\User\Mount\NotAllowed', $userBackends);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
@ -40,7 +40,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
protected function makeTestStorageData() {
|
||||
return $this->makeStorageConfig([
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -59,9 +60,10 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
return [
|
||||
// all users
|
||||
[
|
||||
$this->makeStorageConfig([
|
||||
[
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -70,13 +72,14 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
'applicableUsers' => [],
|
||||
'applicableGroups' => [],
|
||||
'priority' => 15,
|
||||
]),
|
||||
],
|
||||
],
|
||||
// some users
|
||||
[
|
||||
$this->makeStorageConfig([
|
||||
[
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -85,13 +88,14 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
'applicableUsers' => ['user1', 'user2'],
|
||||
'applicableGroups' => [],
|
||||
'priority' => 15,
|
||||
]),
|
||||
],
|
||||
],
|
||||
// some groups
|
||||
[
|
||||
$this->makeStorageConfig([
|
||||
[
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -100,13 +104,14 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
'applicableUsers' => [],
|
||||
'applicableGroups' => ['group1', 'group2'],
|
||||
'priority' => 15,
|
||||
]),
|
||||
],
|
||||
],
|
||||
// both users and groups
|
||||
[
|
||||
$this->makeStorageConfig([
|
||||
[
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -115,7 +120,7 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
'applicableUsers' => ['user1', 'user2'],
|
||||
'applicableGroups' => ['group1', 'group2'],
|
||||
'priority' => 15,
|
||||
]),
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -123,7 +128,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 +138,8 @@ 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->getAuthMechanism(), $newStorage->getAuthMechanism());
|
||||
$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
|
||||
$this->assertEquals($storage->getApplicableUsers(), $newStorage->getApplicableUsers());
|
||||
$this->assertEquals($storage->getApplicableGroups(), $newStorage->getApplicableGroups());
|
||||
|
@ -148,10 +155,12 @@ 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',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -638,7 +647,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
|
||||
$mountPointOptions = current($mountPointData);
|
||||
$this->assertEquals(1, $mountPointOptions['id']);
|
||||
$this->assertEquals('\OC\Files\Storage\SMB', $mountPointOptions['class']);
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
|
||||
$this->assertEquals(15, $mountPointOptions['priority']);
|
||||
$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
|
||||
|
||||
|
@ -678,7 +688,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
$mountPointOptions = current($mountPointData);
|
||||
|
||||
$this->assertEquals(1, $mountPointOptions['id']);
|
||||
$this->assertEquals('\OC\Files\Storage\SMB', $mountPointOptions['class']);
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
|
||||
$this->assertEquals(15, $mountPointOptions['priority']);
|
||||
$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
|
||||
|
||||
|
@ -695,7 +706,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
$mountPointOptions = current($mountPointData);
|
||||
|
||||
$this->assertEquals(1, $mountPointOptions['id']);
|
||||
$this->assertEquals('\OC\Files\Storage\SMB', $mountPointOptions['class']);
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
|
||||
$this->assertEquals(15, $mountPointOptions['priority']);
|
||||
$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
|
||||
|
||||
|
@ -720,13 +732,15 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
$legacyBackendOptions = \OC_Mount_Config::encryptPasswords($legacyBackendOptions);
|
||||
|
||||
$legacyConfig = [
|
||||
'class' => '\OC\Files\Storage\SMB',
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => $legacyBackendOptions,
|
||||
'mountOptions' => ['preview' => false],
|
||||
];
|
||||
// different mount options
|
||||
$legacyConfig2 = [
|
||||
'class' => '\OC\Files\Storage\SMB',
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => $legacyBackendOptions,
|
||||
'mountOptions' => ['preview' => true],
|
||||
];
|
||||
|
@ -737,7 +751,8 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
|
||||
// different config
|
||||
$legacyConfig3 = [
|
||||
'class' => '\OC\Files\Storage\SMB',
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => $legacyBackendOptions2,
|
||||
'mountOptions' => ['preview' => true],
|
||||
];
|
||||
|
@ -811,4 +826,85 @@ class GlobalStoragesServiceTest extends StoragesServiceTest {
|
|||
$this->assertEquals([], $storage4->getApplicableGroups());
|
||||
$this->assertEquals(['preview' => true], $storage4->getMountOptions());
|
||||
}
|
||||
|
||||
public function testReadLegacyConfigNoAuthMechanism() {
|
||||
$configFile = $this->dataDir . '/mount.json';
|
||||
|
||||
$json = [
|
||||
'user' => [
|
||||
'user1' => [
|
||||
'/$user/files/somemount' => [
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => [],
|
||||
'mountOptions' => [],
|
||||
],
|
||||
'/$user/files/othermount' => [
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
|
||||
// no authMechanism
|
||||
'options' => [],
|
||||
'mountOptions' => [],
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
file_put_contents($configFile, json_encode($json));
|
||||
|
||||
$allStorages = $this->service->getAllStorages();
|
||||
|
||||
$this->assertCount(2, $allStorages);
|
||||
|
||||
$storage1 = $allStorages[1];
|
||||
$storage2 = $allStorages[2];
|
||||
|
||||
$this->assertEquals('/somemount', $storage1->getMountPoint());
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage1->getBackend()->getIdentifier());
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $storage1->getAuthMechanism()->getIdentifier());
|
||||
|
||||
$this->assertEquals('/othermount', $storage2->getMountPoint());
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage2->getBackend()->getIdentifier());
|
||||
$this->assertEquals('identifier:\Other\Auth\Mechanism', $storage2->getAuthMechanism()->getIdentifier());
|
||||
}
|
||||
|
||||
public function testReadLegacyConfigClass() {
|
||||
$configFile = $this->dataDir . '/mount.json';
|
||||
|
||||
$json = [
|
||||
'user' => [
|
||||
'user1' => [
|
||||
'/$user/files/somemount' => [
|
||||
'class' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => [],
|
||||
'mountOptions' => [],
|
||||
],
|
||||
'/$user/files/othermount' => [
|
||||
'class' => 'identifier:sftp_alias',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => [],
|
||||
'mountOptions' => [],
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
file_put_contents($configFile, json_encode($json));
|
||||
|
||||
$allStorages = $this->service->getAllStorages();
|
||||
|
||||
$this->assertCount(2, $allStorages);
|
||||
|
||||
$storage1 = $allStorages[1];
|
||||
$storage2 = $allStorages[2];
|
||||
|
||||
$this->assertEquals('/somemount', $storage1->getMountPoint());
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage1->getBackend()->getIdentifier());
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $storage1->getAuthMechanism()->getIdentifier());
|
||||
|
||||
$this->assertEquals('/othermount', $storage2->getMountPoint());
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage2->getBackend()->getIdentifier());
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $storage2->getAuthMechanism()->getIdentifier());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
* @author Robin McCorkell <rmccorkell@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
|
@ -24,6 +25,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 +34,9 @@ abstract class StoragesServiceTest extends \Test\TestCase {
|
|||
*/
|
||||
protected $service;
|
||||
|
||||
/** @var BackendService */
|
||||
protected $backendService;
|
||||
|
||||
/**
|
||||
* Data directory
|
||||
*
|
||||
|
@ -55,6 +60,51 @@ abstract class StoragesServiceTest extends \Test\TestCase {
|
|||
);
|
||||
\OC_Mount_Config::$skipTest = true;
|
||||
|
||||
// prepare BackendService mock
|
||||
$this->backendService =
|
||||
$this->getMockBuilder('\OCA\Files_External\Service\BackendService')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$authMechanisms = [
|
||||
'identifier:\Auth\Mechanism' => $this->getAuthMechMock('null', '\Auth\Mechanism'),
|
||||
'identifier:\Other\Auth\Mechanism' => $this->getAuthMechMock('null', '\Other\Auth\Mechanism'),
|
||||
'identifier:\OCA\Files_External\Lib\Auth\NullMechanism' => $this->getAuthMechMock(),
|
||||
];
|
||||
$this->backendService->method('getAuthMechanism')
|
||||
->will($this->returnCallback(function($class) use ($authMechanisms) {
|
||||
if (isset($authMechanisms[$class])) {
|
||||
return $authMechanisms[$class];
|
||||
}
|
||||
return null;
|
||||
}));
|
||||
$this->backendService->method('getAuthMechanismsByScheme')
|
||||
->will($this->returnCallback(function($schemes) use ($authMechanisms) {
|
||||
return array_filter($authMechanisms, function ($authMech) use ($schemes) {
|
||||
return in_array($authMech->getScheme(), $schemes, true);
|
||||
});
|
||||
}));
|
||||
$this->backendService->method('getAuthMechanisms')
|
||||
->will($this->returnValue($authMechanisms));
|
||||
|
||||
$sftpBackend = $this->getBackendMock('\OCA\Files_External\Lib\Backend\SFTP', '\OC\Files\Storage\SFTP');
|
||||
$backends = [
|
||||
'identifier:\OCA\Files_External\Lib\Backend\SMB' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SMB', '\OC\Files\Storage\SMB'),
|
||||
'identifier:\OCA\Files_External\Lib\Backend\SFTP' => $sftpBackend,
|
||||
'identifier:sftp_alias' => $sftpBackend,
|
||||
];
|
||||
$backends['identifier:\OCA\Files_External\Lib\Backend\SFTP']->method('getLegacyAuthMechanism')
|
||||
->willReturn($authMechanisms['identifier:\Other\Auth\Mechanism']);
|
||||
$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,
|
||||
|
@ -64,6 +114,19 @@ abstract class StoragesServiceTest extends \Test\TestCase {
|
|||
Filesystem::signal_delete_mount,
|
||||
get_class($this), 'deleteHookCallback');
|
||||
|
||||
$containerMock = $this->getMock('\OCP\AppFramework\IAppContainer');
|
||||
$containerMock->method('query')
|
||||
->will($this->returnCallback(function($name) {
|
||||
if ($name === 'OCA\Files_External\Service\BackendService') {
|
||||
return $this->backendService;
|
||||
}
|
||||
}));
|
||||
|
||||
\OC_Mount_Config::$app = $this->getMockBuilder('\OCA\Files_External\Appinfo\Application')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
\OC_Mount_Config::$app->method('getContainer')
|
||||
->willReturn($containerMock);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
|
@ -71,6 +134,29 @@ 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('getIdentifier')
|
||||
->willReturn('identifier:'.$class);
|
||||
return $backend;
|
||||
}
|
||||
|
||||
protected function getAuthMechMock($scheme = 'null', $class = '\OCA\Files_External\Lib\Auth\NullMechanism') {
|
||||
$authMech = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\AuthMechanism')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$authMech->method('getScheme')
|
||||
->willReturn($scheme);
|
||||
$authMech->method('getIdentifier')
|
||||
->willReturn('identifier:'.$class);
|
||||
|
||||
return $authMech;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a StorageConfig instance based on array data
|
||||
*
|
||||
|
@ -84,7 +170,22 @@ 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['backendIdentifier']);
|
||||
}
|
||||
if (!isset($data['backend'])) {
|
||||
throw new \Exception('oops, no backend');
|
||||
}
|
||||
if (!isset($data['authMechanism'])) {
|
||||
$data['authMechanism'] = $this->backendService->getAuthMechanism($data['authMechanismIdentifier']);
|
||||
}
|
||||
if (!isset($data['authMechanism'])) {
|
||||
throw new \Exception('oops, no auth mechanism');
|
||||
}
|
||||
$storage->setBackend($data['backend']);
|
||||
$storage->setAuthMechanism($data['authMechanism']);
|
||||
$storage->setBackendOptions($data['backendOptions']);
|
||||
if (isset($data['applicableUsers'])) {
|
||||
$storage->setApplicableUsers($data['applicableUsers']);
|
||||
|
@ -106,16 +207,22 @@ abstract class StoragesServiceTest extends \Test\TestCase {
|
|||
* @expectedException \OCA\Files_external\NotFoundException
|
||||
*/
|
||||
public function testNonExistingStorage() {
|
||||
$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
|
||||
$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
|
||||
$storage = new StorageConfig(255);
|
||||
$storage->setMountPoint('mountpoint');
|
||||
$storage->setBackendClass('\OC\Files\Storage\SMB');
|
||||
$storage->setBackend($backend);
|
||||
$storage->setAuthMechanism($authMechanism);
|
||||
$this->service->updateStorage($storage);
|
||||
}
|
||||
|
||||
public function testDeleteStorage() {
|
||||
$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
|
||||
$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
|
||||
$storage = new StorageConfig(255);
|
||||
$storage->setMountPoint('mountpoint');
|
||||
$storage->setBackendClass('\OC\Files\Storage\SMB');
|
||||
$storage->setBackend($backend);
|
||||
$storage->setAuthMechanism($authMechanism);
|
||||
$storage->setBackendOptions(['password' => 'testPassword']);
|
||||
|
||||
$newStorage = $this->service->addStorage($storage);
|
||||
|
@ -140,6 +247,64 @@ abstract class StoragesServiceTest extends \Test\TestCase {
|
|||
$this->service->removeStorage(255);
|
||||
}
|
||||
|
||||
public function testCreateStorage() {
|
||||
$mountPoint = 'mount';
|
||||
$backendIdentifier = 'identifier:\OCA\Files_External\Lib\Backend\SMB';
|
||||
$authMechanismIdentifier = 'identifier:\Auth\Mechanism';
|
||||
$backendOptions = ['param' => 'foo', 'param2' => 'bar'];
|
||||
$mountOptions = ['option' => 'foobar'];
|
||||
$applicableUsers = ['user1', 'user2'];
|
||||
$applicableGroups = ['group'];
|
||||
$priority = 123;
|
||||
|
||||
$backend = $this->backendService->getBackend($backendIdentifier);
|
||||
$authMechanism = $this->backendService->getAuthMechanism($authMechanismIdentifier);
|
||||
|
||||
$storage = $this->service->createStorage(
|
||||
$mountPoint,
|
||||
$backendIdentifier,
|
||||
$authMechanismIdentifier,
|
||||
$backendOptions,
|
||||
$mountOptions,
|
||||
$applicableUsers,
|
||||
$applicableGroups,
|
||||
$priority
|
||||
);
|
||||
|
||||
$this->assertEquals('/'.$mountPoint, $storage->getMountPoint());
|
||||
$this->assertEquals($backend, $storage->getBackend());
|
||||
$this->assertEquals($authMechanism, $storage->getAuthMechanism());
|
||||
$this->assertEquals($backendOptions, $storage->getBackendOptions());
|
||||
$this->assertEquals($mountOptions, $storage->getMountOptions());
|
||||
$this->assertEquals($applicableUsers, $storage->getApplicableUsers());
|
||||
$this->assertEquals($applicableGroups, $storage->getApplicableGroups());
|
||||
$this->assertEquals($priority, $storage->getPriority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testCreateStorageInvalidClass() {
|
||||
$this->service->createStorage(
|
||||
'mount',
|
||||
'identifier:\OC\Not\A\Backend',
|
||||
'identifier:\Auth\Mechanism',
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testCreateStorageInvalidAuthMechanismClass() {
|
||||
$this->service->createStorage(
|
||||
'mount',
|
||||
'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'identifier:\Not\An\Auth\Mechanism',
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
public static function createHookCallback($params) {
|
||||
self::$hookCalls[] = array(
|
||||
'signal' => Filesystem::signal_create_mount,
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
<?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\Tests\Service;
|
||||
|
||||
use \OCA\Files_External\Service\UserGlobalStoragesService;
|
||||
use \OCP\IGroupManager;
|
||||
|
||||
use \OCA\Files_External\Lib\StorageConfig;
|
||||
|
||||
class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
|
||||
|
||||
protected $groupManager;
|
||||
|
||||
protected $globalStoragesService;
|
||||
|
||||
protected $user;
|
||||
|
||||
const USER_ID = 'test_user';
|
||||
const GROUP_ID = 'test_group';
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->globalStoragesService = $this->service;
|
||||
|
||||
$this->user = new \OC\User\User(self::USER_ID, null);
|
||||
$userSession = $this->getMock('\OCP\IUserSession');
|
||||
$userSession
|
||||
->expects($this->any())
|
||||
->method('getUser')
|
||||
->will($this->returnValue($this->user));
|
||||
|
||||
$this->groupManager = $this->getMock('\OCP\IGroupManager');
|
||||
$this->groupManager->method('isInGroup')
|
||||
->will($this->returnCallback(function($userId, $groupId) {
|
||||
if ($userId === self::USER_ID && $groupId === self::GROUP_ID) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
|
||||
$this->service = new UserGlobalStoragesService(
|
||||
$this->backendService,
|
||||
$userSession,
|
||||
$this->groupManager
|
||||
);
|
||||
}
|
||||
|
||||
public function applicableStorageProvider() {
|
||||
return [
|
||||
[[], [], true],
|
||||
|
||||
// not applicable cases
|
||||
[['user1'], [], false],
|
||||
[[], ['group1'], false],
|
||||
[['user1'], ['group1'], false],
|
||||
|
||||
// applicable cases
|
||||
[[self::USER_ID], [], true],
|
||||
[[], [self::GROUP_ID], true],
|
||||
[[self::USER_ID], ['group1'], true],
|
||||
[['user1'], [self::GROUP_ID], true],
|
||||
|
||||
// sanity checks
|
||||
[['user1', 'user2', self::USER_ID, 'user3'], [], true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider applicableStorageProvider
|
||||
*/
|
||||
public function testGetStorageWithApplicable($applicableUsers, $applicableGroups, $isVisible) {
|
||||
$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
|
||||
$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
|
||||
|
||||
$storage = new StorageConfig();
|
||||
$storage->setMountPoint('mountpoint');
|
||||
$storage->setBackend($backend);
|
||||
$storage->setAuthMechanism($authMechanism);
|
||||
$storage->setBackendOptions(['password' => 'testPassword']);
|
||||
$storage->setApplicableUsers($applicableUsers);
|
||||
$storage->setApplicableGroups($applicableGroups);
|
||||
|
||||
$newStorage = $this->globalStoragesService->addStorage($storage);
|
||||
|
||||
$storages = $this->service->getAllStorages();
|
||||
if ($isVisible) {
|
||||
$this->assertEquals(1, count($storages));
|
||||
$retrievedStorage = $this->service->getStorage($newStorage->getId());
|
||||
$this->assertEquals('/mountpoint', $retrievedStorage->getMountPoint());
|
||||
} else {
|
||||
$this->assertEquals(0, count($storages));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \DomainException
|
||||
*/
|
||||
public function testAddStorage($storageParams = null) {
|
||||
$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
|
||||
$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
|
||||
|
||||
$storage = new StorageConfig(255);
|
||||
$storage->setMountPoint('mountpoint');
|
||||
$storage->setBackend($backend);
|
||||
$storage->setAuthMechanism($authMechanism);
|
||||
$storage->setBackendOptions(['password' => 'testPassword']);
|
||||
|
||||
$this->service->addStorage($storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \DomainException
|
||||
*/
|
||||
public function testUpdateStorage($storageParams = null) {
|
||||
$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
|
||||
$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
|
||||
|
||||
$storage = new StorageConfig(255);
|
||||
$storage->setMountPoint('mountpoint');
|
||||
$storage->setBackend($backend);
|
||||
$storage->setAuthMechanism($authMechanism);
|
||||
$storage->setBackendOptions(['password' => 'testPassword']);
|
||||
|
||||
$newStorage = $this->globalStoragesService->addStorage($storage);
|
||||
|
||||
$retrievedStorage = $this->service->getStorage($newStorage->getId());
|
||||
$retrievedStorage->setMountPoint('abc');
|
||||
$this->service->updateStorage($retrievedStorage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \DomainException
|
||||
*/
|
||||
public function testDeleteStorage() {
|
||||
$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
|
||||
$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
|
||||
|
||||
$storage = new StorageConfig(255);
|
||||
$storage->setMountPoint('mountpoint');
|
||||
$storage->setBackend($backend);
|
||||
$storage->setAuthMechanism($authMechanism);
|
||||
$storage->setBackendOptions(['password' => 'testPassword']);
|
||||
|
||||
$newStorage = $this->globalStoragesService->addStorage($storage);
|
||||
$this->assertEquals(1, $newStorage->getId());
|
||||
|
||||
$this->service->removeStorage(1);
|
||||
}
|
||||
|
||||
public function testHooksAddStorage($a = null, $b = null, $c = null) {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testHooksUpdateStorage($a = null, $b = null, $c = null, $d = null, $e = null) {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testHooksRenameMountPoint() {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testHooksDeleteStorage($a = null, $b = null, $c = null) {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testLegacyConfigConversionApplicableAll() {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testLegacyConfigConversionApplicableUserAndGroup() {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testReadLegacyConfigAndGenerateConfigId() {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testReadLegacyConfigNoAuthMechanism() {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testReadLegacyConfigClass() {
|
||||
// we don't test this here
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 . '/');
|
||||
|
@ -54,7 +54,8 @@ class UserStoragesServiceTest extends StoragesServiceTest {
|
|||
private function makeTestStorageData() {
|
||||
return $this->makeStorageConfig([
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -76,7 +77,8 @@ 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->getAuthMechanism(), $newStorage->getAuthMechanism());
|
||||
$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
|
||||
$this->assertEquals(1, $newStorage->getId());
|
||||
$this->assertEquals(0, $newStorage->getStatus());
|
||||
|
@ -98,7 +100,8 @@ class UserStoragesServiceTest extends StoragesServiceTest {
|
|||
public function testUpdateStorage() {
|
||||
$storage = $this->makeStorageConfig([
|
||||
'mountPoint' => 'mountpoint',
|
||||
'backendClass' => '\OC\Files\Storage\SMB',
|
||||
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
|
||||
'backendOptions' => [
|
||||
'option1' => 'value1',
|
||||
'option2' => 'value2',
|
||||
|
@ -191,7 +194,8 @@ class UserStoragesServiceTest extends StoragesServiceTest {
|
|||
|
||||
$mountPointOptions = current($mountPointData);
|
||||
$this->assertEquals(1, $mountPointOptions['id']);
|
||||
$this->assertEquals('\OC\Files\Storage\SMB', $mountPointOptions['class']);
|
||||
$this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
|
||||
$this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
|
||||
$this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
|
||||
|
||||
$backendOptions = $mountPointOptions['options'];
|
||||
|
@ -214,13 +218,15 @@ class UserStoragesServiceTest extends StoragesServiceTest {
|
|||
$legacyBackendOptions = \OC_Mount_Config::encryptPasswords($legacyBackendOptions);
|
||||
|
||||
$legacyConfig = [
|
||||
'class' => '\OC\Files\Storage\SMB',
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => $legacyBackendOptions,
|
||||
'mountOptions' => ['preview' => false],
|
||||
];
|
||||
// different mount options
|
||||
$legacyConfig2 = [
|
||||
'class' => '\OC\Files\Storage\SMB',
|
||||
'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
|
||||
'authMechanism' => 'identifier:\Auth\Mechanism',
|
||||
'options' => $legacyBackendOptions,
|
||||
'mountOptions' => ['preview' => true],
|
||||
];
|
||||
|
|
|
@ -26,9 +26,22 @@ 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('getIdentifier')
|
||||
->willReturn('storage::identifier');
|
||||
|
||||
$authMech = $this->getMockBuilder('\OCA\Files_External\Lib\Auth\AuthMechanism')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$authMech->method('getIdentifier')
|
||||
->willReturn('auth::identifier');
|
||||
|
||||
$storageConfig = new StorageConfig(1);
|
||||
$storageConfig->setMountPoint('test');
|
||||
$storageConfig->setBackendClass('\OC\Files\Storage\SMB');
|
||||
$storageConfig->setBackend($backend);
|
||||
$storageConfig->setAuthMechanism($authMech);
|
||||
$storageConfig->setBackendOptions(['user' => 'test', 'password' => 'password123']);
|
||||
$storageConfig->setPriority(128);
|
||||
$storageConfig->setApplicableUsers(['user1', 'user2']);
|
||||
|
@ -39,7 +52,8 @@ class StorageConfigTest extends \Test\TestCase {
|
|||
|
||||
$this->assertEquals(1, $json['id']);
|
||||
$this->assertEquals('/test', $json['mountPoint']);
|
||||
$this->assertEquals('\OC\Files\Storage\SMB', $json['backendClass']);
|
||||
$this->assertEquals('storage::identifier', $json['backend']);
|
||||
$this->assertEquals('auth::identifier', $json['authMechanism']);
|
||||
$this->assertEquals('test', $json['backendOptions']['user']);
|
||||
$this->assertEquals('password123', $json['backendOptions']['password']);
|
||||
$this->assertEquals(128, $json['priority']);
|
||||
|
|
|
@ -431,14 +431,16 @@ table.grid td.date{
|
|||
}
|
||||
|
||||
span.success {
|
||||
background: #37ce02;
|
||||
border-radius: 3px;
|
||||
background: #37ce02;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
span.error {
|
||||
background: #ce3702;
|
||||
background: #ce3702;
|
||||
}
|
||||
span.indeterminate {
|
||||
background: #e6db00;
|
||||
border-radius: 40% 0;
|
||||
}
|
||||
|
||||
|
||||
/* PASSWORD */
|
||||
.strengthify-wrapper {
|
||||
|
|
|
@ -108,10 +108,7 @@ $clients = array(
|
|||
$enableCertImport = false;
|
||||
$externalStorageEnabled = \OC::$server->getAppManager()->isEnabledForUser('files_external');
|
||||
if ($externalStorageEnabled) {
|
||||
$backends = OC_Mount_Config::getPersonalBackends();
|
||||
if (!empty($backends)) {
|
||||
$enableCertImport = true;
|
||||
}
|
||||
$enableCertImport = true;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue