From 19bc5a452a97788c9153c05523cf6dd61d9c111c Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Wed, 12 Aug 2015 22:10:30 +0100 Subject: Migrate Swift external storage to new API The Rackspace/OpenStack differences have been split into separate auth mechanisms, with correct legacy migration --- apps/files_external/lib/backend/swift.php | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 apps/files_external/lib/backend/swift.php (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/lib/backend/swift.php b/apps/files_external/lib/backend/swift.php new file mode 100644 index 00000000000..9f01a923638 --- /dev/null +++ b/apps/files_external/lib/backend/swift.php @@ -0,0 +1,60 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Backend; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\Backend\Backend; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; +use \OCA\Files_External\Service\BackendService; +use \OCA\Files_External\Lib\Auth\OpenStack\OpenStack; +use \OCA\Files_External\Lib\Auth\OpenStack\Rackspace; + +class Swift extends Backend { + + public function __construct(IL10N $l, OpenStack $openstackAuth, Rackspace $rackspaceAuth) { + $this + ->setIdentifier('swift') + ->addIdentifierAlias('\OC\Files\Storage\Swift') // legacy compat + ->setStorageClass('\OC\Files\Storage\Swift') + ->setText($l->t('OpenStack Object Storage')) + ->addParameters([ + (new DefinitionParameter('service_name', $l->t('Service name'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('region', $l->t('Region'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('bucket', $l->t('Bucket'))), + (new DefinitionParameter('timeout', $l->t('Request timeout (seconds)'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ]) + ->setDependencyCheck('\OC\Files\Storage\Swift::checkDependencies') + ->addAuthScheme(AuthMechanism::SCHEME_OPENSTACK) + ->setLegacyAuthMechanismCallback(function(array $params) use ($openstackAuth, $rackspaceAuth) { + if (isset($params['key'])) { + return $rackspaceAuth; + } + return $openstackAuth; + }) + ; + } + +} -- cgit v1.2.3 From cb1ef827028126dd55c21fc3f3720723e5cc25a6 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Wed, 12 Aug 2015 22:14:42 +0100 Subject: Migrate SMB_OC external storage to new API SMB_OC has been merged with SMB, via the identifier aliases mechanism. Legacy migration is done to the Session Credentials password mechanism --- apps/files_external/appinfo/app.php | 16 ---- apps/files_external/appinfo/application.php | 1 + apps/files_external/lib/backend/smb_oc.php | 67 +++++++++++++++ apps/files_external/lib/smb_oc.php | 126 ---------------------------- 4 files changed, 68 insertions(+), 142 deletions(-) create mode 100644 apps/files_external/lib/backend/smb_oc.php delete mode 100644 apps/files_external/lib/smb_oc.php (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index da24dfd819a..351b87c4c8b 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -37,7 +37,6 @@ OC::$CLASSPATH['OC\Files\Storage\OwnCloud'] = 'files_external/lib/owncloud.php'; OC::$CLASSPATH['OC\Files\Storage\Google'] = 'files_external/lib/google.php'; OC::$CLASSPATH['OC\Files\Storage\Swift'] = 'files_external/lib/swift.php'; OC::$CLASSPATH['OC\Files\Storage\SMB'] = 'files_external/lib/smb.php'; -OC::$CLASSPATH['OC\Files\Storage\SMB_OC'] = 'files_external/lib/smb_oc.php'; OC::$CLASSPATH['OC\Files\Storage\AmazonS3'] = 'files_external/lib/amazons3.php'; OC::$CLASSPATH['OC\Files\Storage\Dropbox'] = 'files_external/lib/dropbox.php'; OC::$CLASSPATH['OC\Files\Storage\SFTP'] = 'files_external/lib/sftp.php'; @@ -68,21 +67,6 @@ if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == ' // connecting hooks OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\OC_Mount_Config', 'initMountPointsHook'); -OCP\Util::connectHook('OC_User', 'post_login', 'OC\Files\Storage\SMB_OC', 'login'); - -if (!OC_Util::runningOnWindows()) { - OC_Mount_Config::registerBackend('\OC\Files\Storage\SMB_OC', [ - 'backend' => (string)$l->t('SMB / CIFS using OC login'), - 'priority' => 90, - 'configuration' => [ - 'host' => (string)$l->t('Host'), - 'username_as_share' => '!'.$l->t('Username as share'), - 'share' => '&'.$l->t('Share'), - 'root' => '&'.$l->t('Remote subfolder'), - ], - 'has_dependencies' => true, - ]); -} OC_Mount_Config::registerBackend('\OC\Files\Storage\SFTP_Key', [ 'backend' => (string)$l->t('SFTP with secret key login'), diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index 81e60658c8c..e5275c29b39 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -74,6 +74,7 @@ class Application extends App { if (!\OC_Util::runningOnWindows()) { $service->registerBackends([ $container->query('OCA\Files_External\Lib\Backend\SMB'), + $container->query('OCA\Files_External\Lib\Backend\SMB_OC'), ]); } } diff --git a/apps/files_external/lib/backend/smb_oc.php b/apps/files_external/lib/backend/smb_oc.php new file mode 100644 index 00000000000..cae3818c76c --- /dev/null +++ b/apps/files_external/lib/backend/smb_oc.php @@ -0,0 +1,67 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Backend; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\Backend\Backend; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; +use \OCA\Files_External\Service\BackendService; +use \OCA\Files_External\Lib\Auth\Password\SessionCredentials; +use \OCA\Files_External\Lib\StorageConfig; + +/** + * Deprecated SMB_OC class - use SMB with the password::sessioncredentials auth mechanism + */ +class SMB_OC extends Backend { + + public function __construct(IL10N $l, SessionCredentials $legacyAuth) { + $this + ->setIdentifier('\OC\Files\Storage\SMB_OC') + ->setStorageClass('\OC\Files\Storage\SMB') + ->setText($l->t('SMB / CIFS using OC login [DEPRECATED]')) + ->addParameters([ + (new DefinitionParameter('host', $l->t('Host'))), + (new DefinitionParameter('username_as_share', $l->t('Username as share'))) + ->setType(DefinitionParameter::VALUE_BOOLEAN), + (new DefinitionParameter('share', $l->t('Share'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('root', $l->t('Remote subfolder'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ]) + ->setDependencyCheck('\OC\Files\Storage\SMB::checkDependencies') + ->setPriority(BackendService::PRIORITY_DEFAULT - 10) + ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) + ->setLegacyAuthMechanism($legacyAuth) + ; + } + + public function manipulateStorageConfig(StorageConfig &$storage) { + $username_as_share = ($storage->getBackendOption('username_as_share') === 'true'); + + if ($this->username_as_share) { + $share = '/' . $storage->getBackendOption('user'); + $storage->setBackendOption('share', $share); + } + } + +} diff --git a/apps/files_external/lib/smb_oc.php b/apps/files_external/lib/smb_oc.php deleted file mode 100644 index 547caa5ecbf..00000000000 --- a/apps/files_external/lib/smb_oc.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @author Morris Jobke - * @author Robin Appelman - * @author Robin McCorkell - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OC\Files\Storage; - - -use Icewind\SMB\Exception\AccessDeniedException; -use Icewind\SMB\Exception\Exception; -use Icewind\SMB\Server; - -class SMB_OC extends SMB { - private $username_as_share; - - /** - * @param array $params - * @throws \Exception - */ - public function __construct($params) { - if (isset($params['host'])) { - $host = $params['host']; - $this->username_as_share = ($params['username_as_share'] === true); - - // dummy credentials, unused, to satisfy constructor - $user = 'foo'; - $password = 'bar'; - if (\OC::$server->getSession()->exists('smb-credentials')) { - $params_auth = json_decode(\OC::$server->getCrypto()->decrypt(\OC::$server->getSession()->get('smb-credentials')), true); - $user = \OC::$server->getSession()->get('loginname'); - $password = $params_auth['password']; - } else { - // assume we are testing from the admin section - } - - $root = isset($params['root']) ? $params['root'] : '/'; - $share = ''; - - if ($this->username_as_share) { - $share = '/' . $user; - } elseif (isset($params['share'])) { - $share = $params['share']; - } else { - throw new \Exception(); - } - parent::__construct(array( - "user" => $user, - "password" => $password, - "host" => $host, - "share" => $share, - "root" => $root - )); - } else { - throw new \Exception(); - } - } - - - /** - * Intercepts the user credentials on login and stores them - * encrypted inside the session if SMB_OC storage is enabled. - * @param array $params - */ - public static function login($params) { - $mountpoints = \OC_Mount_Config::getAbsoluteMountPoints($params['uid']); - $mountpointClasses = array(); - foreach($mountpoints as $mountpoint) { - $mountpointClasses[$mountpoint['class']] = true; - } - if(isset($mountpointClasses['\OC\Files\Storage\SMB_OC'])) { - \OC::$server->getSession()->set('smb-credentials', \OC::$server->getCrypto()->encrypt(json_encode($params))); - } - } - - /** - * @param string $path - * @return boolean - */ - public function isSharable($path) { - return false; - } - - /** - * @param bool $isPersonal - * @return bool - */ - public function test($isPersonal = true) { - if ($isPersonal) { - if ($this->stat('')) { - return true; - } - return false; - } else { - $server = new Server($this->server->getHost(), '', ''); - - try { - $server->listShares(); - return true; - } catch (AccessDeniedException $e) { - // expected due to anonymous login - return true; - } catch (Exception $e) { - return false; - } - } - } -} -- cgit v1.2.3 From 1084e3adc7636787a139b68335112715b187b3bb Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Wed, 12 Aug 2015 22:20:08 +0100 Subject: Migrate SFTP_Key external storage to new API The SFTP backend now supports public key authentication alongside password authentication. --- apps/files_external/appinfo/app.php | 13 -- apps/files_external/appinfo/application.php | 4 + apps/files_external/appinfo/routes.php | 2 +- apps/files_external/js/public_key.js | 46 ++++++ apps/files_external/js/sftp_key.js | 53 ------ apps/files_external/lib/auth/publickey/rsa.php | 65 ++++++++ apps/files_external/lib/backend/sftp.php | 1 + apps/files_external/lib/backend/sftp_key.php | 48 ++++++ apps/files_external/lib/sftp.php | 17 +- apps/files_external/lib/sftp_key.php | 215 ------------------------- 10 files changed, 177 insertions(+), 287 deletions(-) create mode 100644 apps/files_external/js/public_key.js delete mode 100644 apps/files_external/js/sftp_key.js create mode 100644 apps/files_external/lib/auth/publickey/rsa.php create mode 100644 apps/files_external/lib/backend/sftp_key.php delete mode 100644 apps/files_external/lib/sftp_key.php (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 351b87c4c8b..f33012b5f09 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -40,7 +40,6 @@ OC::$CLASSPATH['OC\Files\Storage\SMB'] = 'files_external/lib/smb.php'; OC::$CLASSPATH['OC\Files\Storage\AmazonS3'] = 'files_external/lib/amazons3.php'; OC::$CLASSPATH['OC\Files\Storage\Dropbox'] = 'files_external/lib/dropbox.php'; OC::$CLASSPATH['OC\Files\Storage\SFTP'] = 'files_external/lib/sftp.php'; -OC::$CLASSPATH['OC\Files\Storage\SFTP_Key'] = 'files_external/lib/sftp_key.php'; OC::$CLASSPATH['OC_Mount_Config'] = 'files_external/lib/config.php'; OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php'; @@ -68,17 +67,5 @@ if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == ' // connecting hooks OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\OC_Mount_Config', 'initMountPointsHook'); -OC_Mount_Config::registerBackend('\OC\Files\Storage\SFTP_Key', [ - 'backend' => (string)$l->t('SFTP with secret key login'), - 'priority' => 100, - 'configuration' => array( - 'host' => (string)$l->t('Host'), - 'user' => (string)$l->t('Username'), - 'public_key' => (string)$l->t('Public key'), - 'private_key' => '#private_key', - 'root' => '&'.$l->t('Remote subfolder')), - 'custom' => 'sftp_key', - ] -); $mountProvider = $appContainer->query('OCA\Files_External\Config\ConfigAdapter'); \OC::$server->getMountProviderCollection()->registerProvider($mountProvider); diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index e5275c29b39..ed236af0ec5 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -69,6 +69,7 @@ class Application extends App { $container->query('OCA\Files_External\Lib\Backend\Dropbox'), $container->query('OCA\Files_External\Lib\Backend\Google'), $container->query('OCA\Files_External\Lib\Backend\Swift'), + $container->query('OCA\Files_External\Lib\Backend\SFTP_Key'), ]); if (!\OC_Util::runningOnWindows()) { @@ -103,6 +104,9 @@ class Application extends App { // AuthMechanism::SCHEME_OAUTH2 mechanisms $container->query('OCA\Files_External\Lib\Auth\OAuth2\OAuth2'), + // AuthMechanism::SCHEME_PUBLICKEY mechanisms + $container->query('OCA\Files_External\Lib\Auth\PublicKey\RSA'), + // AuthMechanism::SCHEME_OPENSTACK mechanisms $container->query('OCA\Files_External\Lib\Auth\OpenStack\OpenStack'), $container->query('OCA\Files_External\Lib\Auth\OpenStack\Rackspace'), diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php index 5d7018c3476..a371273e74e 100644 --- a/apps/files_external/appinfo/routes.php +++ b/apps/files_external/appinfo/routes.php @@ -38,7 +38,7 @@ namespace OCA\Files_External\AppInfo; 'routes' => array( array( 'name' => 'Ajax#getSshKeys', - 'url' => '/ajax/sftp_key.php', + 'url' => '/ajax/public_key.php', 'verb' => 'POST', 'requirements' => array() ) diff --git a/apps/files_external/js/public_key.js b/apps/files_external/js/public_key.js new file mode 100644 index 00000000000..a8546067452 --- /dev/null +++ b/apps/files_external/js/public_key.js @@ -0,0 +1,46 @@ +$(document).ready(function() { + + OCA.External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme) { + if (scheme === 'publickey') { + var config = $tr.find('.configuration'); + if ($(config).find('[name="public_key_generate"]').length === 0) { + setupTableRow($tr, config); + } + } + }); + + $('#externalStorage').on('click', '[name="public_key_generate"]', function(event) { + event.preventDefault(); + var tr = $(this).parent().parent(); + generateKeys(tr); + }); + + function setupTableRow(tr, config) { + $(config).append($(document.createElement('input')) + .addClass('button auth-param') + .attr('type', 'button') + .attr('value', t('files_external', 'Generate keys')) + .attr('name', 'public_key_generate') + ); + // If there's no private key, build one + if (0 === $(config).find('[data-parameter="private_key"]').val().length) { + generateKeys(tr); + } + } + + function generateKeys(tr) { + var config = $(tr).find('.configuration'); + + $.post(OC.filePath('files_external', 'ajax', 'public_key.php'), {}, function(result) { + if (result && result.status === 'success') { + $(config).find('[data-parameter="public_key"]').val(result.data.public_key); + $(config).find('[data-parameter="private_key"]').val(result.data.private_key); + OCA.External.Settings.mountConfig.saveStorageConfig(tr, function() { + // Nothing to do + }); + } else { + OC.dialogs.alert(result.data.message, t('files_external', 'Error generating key pair') ); + } + }); + } +}); diff --git a/apps/files_external/js/sftp_key.js b/apps/files_external/js/sftp_key.js deleted file mode 100644 index 55b11b1fac9..00000000000 --- a/apps/files_external/js/sftp_key.js +++ /dev/null @@ -1,53 +0,0 @@ -$(document).ready(function() { - - $('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\SFTP_Key').each(function() { - var tr = $(this); - var config = $(tr).find('.configuration'); - if ($(config).find('.sftp_key').length === 0) { - setupTableRow(tr, config); - } - }); - - // We can't catch the DOM elements being added, but we can pick up when - // they receive focus - $('#externalStorage').on('focus', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\SFTP_Key', function() { - var tr = $(this); - var config = $(tr).find('.configuration'); - - if ($(config).find('.sftp_key').length === 0) { - setupTableRow(tr, config); - } - }); - - $('#externalStorage').on('click', '.sftp_key', function(event) { - event.preventDefault(); - var tr = $(this).parent().parent(); - generateKeys(tr); - }); - - function setupTableRow(tr, config) { - $(config).append($(document.createElement('input')).addClass('button sftp_key') - .attr('type', 'button') - .attr('value', t('files_external', 'Generate keys'))); - // If there's no private key, build one - if (0 === $(config).find('[data-parameter="private_key"]').val().length) { - generateKeys(tr); - } - } - - function generateKeys(tr) { - var config = $(tr).find('.configuration'); - - $.post(OC.filePath('files_external', 'ajax', 'sftp_key.php'), {}, function(result) { - if (result && result.status === 'success') { - $(config).find('[data-parameter="public_key"]').val(result.data.public_key); - $(config).find('[data-parameter="private_key"]').val(result.data.private_key); - OCA.External.mountConfig.saveStorageConfig(tr, function() { - // Nothing to do - }); - } else { - OC.dialogs.alert(result.data.message, t('files_external', 'Error generating key pair') ); - } - }); - } -}); diff --git a/apps/files_external/lib/auth/publickey/rsa.php b/apps/files_external/lib/auth/publickey/rsa.php new file mode 100644 index 00000000000..b5eecb42712 --- /dev/null +++ b/apps/files_external/lib/auth/publickey/rsa.php @@ -0,0 +1,65 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Auth\PublicKey; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; +use \OCA\Files_External\Lib\StorageConfig; +use \OCP\IConfig; +use \phpseclib\Crypt\RSA as RSACrypt; + +/** + * RSA public key authentication + */ +class RSA extends AuthMechanism { + + /** @var IConfig */ + private $config; + + public function __construct(IL10N $l, IConfig $config) { + $this->config = $config; + + $this + ->setIdentifier('publickey::rsa') + ->setScheme(self::SCHEME_PUBLICKEY) + ->setText($l->t('RSA public key')) + ->addParameters([ + (new DefinitionParameter('user', $l->t('Username'))), + (new DefinitionParameter('public_key', $l->t('Public key'))), + (new DefinitionParameter('private_key', 'private_key')) + ->setType(DefinitionParameter::VALUE_HIDDEN), + ]) + ->setCustomJs('public_key') + ; + } + + public function manipulateStorageConfig(StorageConfig &$storage) { + $auth = new RSACrypt(); + $auth->setPassword($this->config->getSystemValue('secret', '')); + if (!$auth->loadKey($storage->getBackendOption('private_key'))) { + throw new \RuntimeException('unable to load private key'); + } + $storage->setBackendOption('public_key_auth', $auth); + } + +} diff --git a/apps/files_external/lib/backend/sftp.php b/apps/files_external/lib/backend/sftp.php index dd0f5d8e2e0..c0bcd27c54b 100644 --- a/apps/files_external/lib/backend/sftp.php +++ b/apps/files_external/lib/backend/sftp.php @@ -43,6 +43,7 @@ class SFTP extends Backend { ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]) ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) + ->addAuthScheme(AuthMechanism::SCHEME_PUBLICKEY) ->setLegacyAuthMechanism($legacyAuth) ; } diff --git a/apps/files_external/lib/backend/sftp_key.php b/apps/files_external/lib/backend/sftp_key.php new file mode 100644 index 00000000000..4a7f565eb19 --- /dev/null +++ b/apps/files_external/lib/backend/sftp_key.php @@ -0,0 +1,48 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Backend; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\Backend\Backend; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; +use \OCA\Files_External\Service\BackendService; +use \OCA\Files_External\Lib\Auth\PublicKey\RSA; + +class SFTP_Key extends Backend { + + public function __construct(IL10N $l, RSA $legacyAuth) { + $this + ->setIdentifier('\OC\Files\Storage\SFTP_Key') + ->setStorageClass('\OC\Files\Storage\SFTP') + ->setText($l->t('SFTP with secret key login [DEPRECATED]')) + ->addParameters([ + (new DefinitionParameter('host', $l->t('Host'))), + (new DefinitionParameter('root', $l->t('Remote subfolder'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ]) + ->addAuthScheme(AuthMechanism::SCHEME_PUBLICKEY) + ->setLegacyAuthMechanism($legacyAuth) + ; + } + +} diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php index 7f921b5342f..921e7283c66 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/sftp.php @@ -40,10 +40,11 @@ use phpseclib\Net\SFTP\Stream; class SFTP extends \OC\Files\Storage\Common { private $host; private $user; - private $password; private $root; private $port = 22; + private $auth; + /** * @var SFTP */ @@ -73,8 +74,15 @@ class SFTP extends \OC\Files\Storage\Common { } $this->user = $params['user']; - $this->password - = isset($params['password']) ? $params['password'] : ''; + + if (isset($params['public_key_auth'])) { + $this->auth = $params['public_key_auth']; + } elseif (isset($params['password'])) { + $this->auth = $params['password']; + } else { + throw new \UnexpectedValueException('no authentication parameters specified'); + } + $this->root = isset($params['root']) ? $this->cleanPath($params['root']) : '/'; @@ -112,7 +120,7 @@ class SFTP extends \OC\Files\Storage\Common { $this->writeHostKeys($hostKeys); } - if (!$this->client->login($this->user, $this->password)) { + if (!$this->client->login($this->user, $this->auth)) { throw new \Exception('Login failed'); } return $this->client; @@ -125,7 +133,6 @@ class SFTP extends \OC\Files\Storage\Common { if ( !isset($this->host) || !isset($this->user) - || !isset($this->password) ) { return false; } diff --git a/apps/files_external/lib/sftp_key.php b/apps/files_external/lib/sftp_key.php deleted file mode 100644 index a193b323678..00000000000 --- a/apps/files_external/lib/sftp_key.php +++ /dev/null @@ -1,215 +0,0 @@ - - * @author Morris Jobke - * @author Ross Nicoll - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ -namespace OC\Files\Storage; - -use phpseclib\Crypt\RSA; - -class SFTP_Key extends \OC\Files\Storage\SFTP { - private $publicKey; - private $privateKey; - - /** - * {@inheritdoc} - */ - public function __construct($params) { - parent::__construct($params); - $this->publicKey = $params['public_key']; - $this->privateKey = $params['private_key']; - } - - /** - * Returns the connection. - * - * @return \phpseclib\Net\SFTP connected client instance - * @throws \Exception when the connection failed - */ - public function getConnection() { - if (!is_null($this->client)) { - return $this->client; - } - - $hostKeys = $this->readHostKeys(); - $this->client = new \phpseclib\Net\SFTP($this->getHost()); - - // The SSH Host Key MUST be verified before login(). - $currentHostKey = $this->client->getServerPublicHostKey(); - if (array_key_exists($this->getHost(), $hostKeys)) { - if ($hostKeys[$this->getHost()] !== $currentHostKey) { - throw new \Exception('Host public key does not match known key'); - } - } else { - $hostKeys[$this->getHost()] = $currentHostKey; - $this->writeHostKeys($hostKeys); - } - - $key = $this->getPrivateKey(); - if (is_null($key)) { - throw new \Exception('Secret key could not be loaded'); - } - if (!$this->client->login($this->getUser(), $key)) { - throw new \Exception('Login failed'); - } - return $this->client; - } - - /** - * Returns the private key to be used for authentication to the remote server. - * - * @return RSA instance or null in case of a failure to load the key. - */ - private function getPrivateKey() { - $key = new RSA(); - $key->setPassword(\OC::$server->getConfig()->getSystemValue('secret', '')); - if (!$key->loadKey($this->privateKey)) { - // Should this exception rather than return null? - return null; - } - return $key; - } - - /** - * Throws an exception if the provided host name/address is invalid (cannot be resolved - * and is not an IPv4 address). - * - * @return true; never returns in case of a problem, this return value is used just to - * make unit tests happy. - */ - public function assertHostAddressValid($hostname) { - // TODO: Should handle IPv6 addresses too - if (!preg_match('/^\d+\.\d+\.\d+\.\d+$/', $hostname) && gethostbyname($hostname) === $hostname) { - // Hostname is not an IPv4 address and cannot be resolved via DNS - throw new \InvalidArgumentException('Cannot resolve hostname.'); - } - return true; - } - - /** - * Throws an exception if the provided port number is invalid (cannot be resolved - * and is not an IPv4 address). - * - * @return true; never returns in case of a problem, this return value is used just to - * make unit tests happy. - */ - public function assertPortNumberValid($port) { - if (!preg_match('/^\d+$/', $port)) { - throw new \InvalidArgumentException('Port number must be a number.'); - } - if ($port < 0 || $port > 65535) { - throw new \InvalidArgumentException('Port number must be between 0 and 65535 inclusive.'); - } - return true; - } - - /** - * Replaces anything that's not an alphanumeric character or "." in a hostname - * with "_", to make it safe for use as part of a file name. - */ - protected function sanitizeHostName($name) { - return preg_replace('/[^\d\w\._]/', '_', $name); - } - - /** - * Replaces anything that's not an alphanumeric character or "_" in a username - * with "_", to make it safe for use as part of a file name. - */ - protected function sanitizeUserName($name) { - return preg_replace('/[^\d\w_]/', '_', $name); - } - - public function test() { - - // FIXME: Use as expression in empty once PHP 5.4 support is dropped - $host = $this->getHost(); - if (empty($host)) { - \OC::$server->getLogger()->warning('Hostname has not been specified'); - return false; - } - // FIXME: Use as expression in empty once PHP 5.4 support is dropped - $user = $this->getUser(); - if (empty($user)) { - \OC::$server->getLogger()->warning('Username has not been specified'); - return false; - } - if (!isset($this->privateKey)) { - \OC::$server->getLogger()->warning('Private key was missing from the request'); - return false; - } - - // Sanity check the host - $hostParts = explode(':', $this->getHost()); - try { - if (count($hostParts) == 1) { - $hostname = $hostParts[0]; - $this->assertHostAddressValid($hostname); - } else if (count($hostParts) == 2) { - $hostname = $hostParts[0]; - $this->assertHostAddressValid($hostname); - $this->assertPortNumberValid($hostParts[1]); - } else { - throw new \Exception('Host connection string is invalid.'); - } - } catch(\Exception $e) { - \OC::$server->getLogger()->warning($e->getMessage()); - return false; - } - - // Validate the key - $key = $this->getPrivateKey(); - if (is_null($key)) { - \OC::$server->getLogger()->warning('Secret key could not be loaded'); - return false; - } - - try { - if ($this->getConnection()->nlist() === false) { - return false; - } - } catch(\Exception $e) { - // We should be throwing a more specific error, so we're not just catching - // Exception here - \OC::$server->getLogger()->warning($e->getMessage()); - return false; - } - - // Save the key somewhere it can easily be extracted later - if (\OC::$server->getUserSession()->getUser()) { - $view = new \OC\Files\View('/'.\OC::$server->getUserSession()->getUser()->getUId().'/files_external/sftp_keys'); - if (!$view->is_dir('')) { - if (!$view->mkdir('')) { - \OC::$server->getLogger()->warning('Could not create secret key directory.'); - return false; - } - } - $key_filename = $this->sanitizeUserName($this->getUser()).'@'.$this->sanitizeHostName($hostname).'.pub'; - $key_file = $view->fopen($key_filename, "w"); - if ($key_file) { - fwrite($key_file, $this->publicKey); - fclose($key_file); - } else { - \OC::$server->getLogger()->warning('Could not write secret key file.'); - } - } - - return true; - } -} -- cgit v1.2.3 From cc88c5f4b84da57c425cbdb7dc8b391b1942b503 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Fri, 28 Aug 2015 15:52:29 +0100 Subject: Implement more fine-grained external storage permissions model VisibilityTrait -> PermissionsTrait PermissionsTrait stores two sets of data, $permissions and $allowedPermissions (analogous to $visibility and $allowedVisibility of VisibilityTrait). Each set is a map of user type ('admin' or 'personal') to permissions (mounting permission, create permission). The result is that a backend can now be restricted for creation, while still allowing it to be mounted. This is useful for deprecating backends or auth mechanisms, preventing new storages being created, while still allowing existing storages to be mounted. --- .../controller/userstoragescontroller.php | 2 +- apps/files_external/lib/auth/authmechanism.php | 6 +- apps/files_external/lib/backend/backend.php | 6 +- apps/files_external/lib/backend/local.php | 2 +- apps/files_external/lib/permissionstrait.php | 164 +++++++++++++++++++++ apps/files_external/lib/visibilitytrait.php | 136 ----------------- apps/files_external/personal.php | 8 +- apps/files_external/service/backendservice.php | 68 ++------- apps/files_external/settings.php | 16 +- apps/files_external/templates/settings.php | 2 +- .../tests/controller/storagescontrollertest.php | 8 +- .../controller/userstoragescontrollertest.php | 4 +- .../tests/service/backendservicetest.php | 28 +--- 13 files changed, 212 insertions(+), 238 deletions(-) create mode 100644 apps/files_external/lib/permissionstrait.php delete mode 100644 apps/files_external/lib/visibilitytrait.php (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/controller/userstoragescontroller.php b/apps/files_external/controller/userstoragescontroller.php index 0d41e088a76..9baac3a8031 100644 --- a/apps/files_external/controller/userstoragescontroller.php +++ b/apps/files_external/controller/userstoragescontroller.php @@ -79,7 +79,7 @@ class UserStoragesController extends StoragesController { // Prevent non-admin users from mounting local storage and other disabled backends /** @var Backend */ $backend = $storage->getBackend(); - if (!$backend->isVisibleFor(BackendService::VISIBILITY_PERSONAL)) { + if (!$backend->isPermitted(BackendService::USER_PERSONAL, BackendService::PERMISSION_MOUNT)) { return new DataResponse( array( 'message' => (string)$this->l10n->t('Admin-only storage backend "%s"', [ diff --git a/apps/files_external/lib/auth/authmechanism.php b/apps/files_external/lib/auth/authmechanism.php index 11d99bb330d..ddc0c6a4dca 100644 --- a/apps/files_external/lib/auth/authmechanism.php +++ b/apps/files_external/lib/auth/authmechanism.php @@ -22,7 +22,7 @@ namespace OCA\Files_External\Lib\Auth; use \OCA\Files_External\Lib\StorageConfig; -use \OCA\Files_External\Lib\VisibilityTrait; +use \OCA\Files_External\Lib\PermissionsTrait; use \OCA\Files_External\Lib\IdentifierTrait; use \OCA\Files_External\Lib\FrontendDefinitionTrait; use \OCA\Files_External\Lib\StorageModifierTrait; @@ -40,7 +40,7 @@ use \OCA\Files_External\Lib\StorageModifierTrait; * scheme, which are provided from the authentication mechanism. * * This class uses the following traits: - * - VisibilityTrait + * - PermissionsTrait * Restrict usage to admin-only/none * - FrontendDefinitionTrait * Specify configuration parameters and other definitions @@ -58,7 +58,7 @@ class AuthMechanism implements \JsonSerializable { const SCHEME_PUBLICKEY = 'publickey'; const SCHEME_OPENSTACK = 'openstack'; - use VisibilityTrait; + use PermissionsTrait; use FrontendDefinitionTrait; use StorageModifierTrait; use IdentifierTrait; diff --git a/apps/files_external/lib/backend/backend.php b/apps/files_external/lib/backend/backend.php index 90d5d38ed94..2a2add3ac59 100644 --- a/apps/files_external/lib/backend/backend.php +++ b/apps/files_external/lib/backend/backend.php @@ -22,7 +22,7 @@ namespace OCA\Files_External\Lib\Backend; use \OCA\Files_External\Lib\StorageConfig; -use \OCA\Files_External\Lib\VisibilityTrait; +use \OCA\Files_External\Lib\PermissionsTrait; use \OCA\Files_External\Lib\FrontendDefinitionTrait; use \OCA\Files_External\Lib\PriorityTrait; use \OCA\Files_External\Lib\DependencyTrait; @@ -43,7 +43,7 @@ use \OCA\Files_External\Lib\Auth\AuthMechanism; * scheme, which are provided from the authentication mechanism. * * This class uses the following traits: - * - VisibilityTrait + * - PermissionsTrait * Restrict usage to admin-only/none * - FrontendDefinitionTrait * Specify configuration parameters and other definitions @@ -56,7 +56,7 @@ use \OCA\Files_External\Lib\Auth\AuthMechanism; */ class Backend implements \JsonSerializable { - use VisibilityTrait; + use PermissionsTrait; use FrontendDefinitionTrait; use PriorityTrait; use DependencyTrait; diff --git a/apps/files_external/lib/backend/local.php b/apps/files_external/lib/backend/local.php index a80b437fab7..a6635491b6e 100644 --- a/apps/files_external/lib/backend/local.php +++ b/apps/files_external/lib/backend/local.php @@ -39,7 +39,7 @@ class Local extends Backend { ->addParameters([ (new DefinitionParameter('datadir', $l->t('Location'))), ]) - ->setAllowedVisibility(BackendService::VISIBILITY_ADMIN) + ->setAllowedPermissions(BackendService::USER_PERSONAL, BackendService::PERMISSION_NONE) ->setPriority(BackendService::PRIORITY_DEFAULT + 50) ->addAuthScheme(AuthMechanism::SCHEME_NULL) ->setLegacyAuthMechanism($legacyAuth) diff --git a/apps/files_external/lib/permissionstrait.php b/apps/files_external/lib/permissionstrait.php new file mode 100644 index 00000000000..8509a01e422 --- /dev/null +++ b/apps/files_external/lib/permissionstrait.php @@ -0,0 +1,164 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib; + +use \OCA\Files_External\Service\BackendService; + +/** + * Trait to implement backend and auth mechanism permissions + * + * For user type constants, see BackendService::USER_* + * For permission constants, see BackendService::PERMISSION_* + */ +trait PermissionsTrait { + + /** @var array [user type => permissions] */ + protected $permissions = [ + BackendService::USER_PERSONAL => BackendService::PERMISSION_DEFAULT, + BackendService::USER_ADMIN => BackendService::PERMISSION_DEFAULT, + ]; + + /** @var array [user type => allowed permissions] */ + protected $allowedPermissions = [ + BackendService::USER_PERSONAL => BackendService::PERMISSION_DEFAULT, + BackendService::USER_ADMIN => BackendService::PERMISSION_DEFAULT, + ]; + + /** + * @param string $userType + * @return int + */ + public function getPermissions($userType) { + if (isset($this->permissions[$userType])) { + return $this->permissions[$userType]; + } + return BackendService::PERMISSION_NONE; + } + + /** + * Check if the user type has permission + * + * @param string $userType + * @param int $permission + * @return bool + */ + public function isPermitted($userType, $permission) { + if ($this->getPermissions($userType) & $permission) { + return true; + } + return false; + } + + /** + * @param string $userType + * @param int $permissions + * @return self + */ + public function setPermissions($userType, $permissions) { + $this->permissions[$userType] = $permissions; + $this->allowedPermissions[$userType] = + $this->getAllowedPermissions($userType) | $permissions; + return $this; + } + + /** + * @param string $userType + * @param int $permission + * @return self + */ + public function addPermission($userType, $permission) { + return $this->setPermissions($userType, + $this->getPermissions($userType) | $permission + ); + } + + /** + * @param string $userType + * @param int $permission + * @return self + */ + public function removePermission($userType, $permission) { + return $this->setPermissions($userType, + $this->getPermissions($userType) & ~$permission + ); + } + + /** + * @param string $userType + * @return int + */ + public function getAllowedPermissions($userType) { + if (isset($this->allowedPermissions[$userType])) { + return $this->allowedPermissions[$userType]; + } + return BackendService::PERMISSION_NONE; + } + + /** + * Check if the user type has an allowed permission + * + * @param string $userType + * @param int $permission + * @return bool + */ + public function isAllowedPermitted($userType, $permission) { + if ($this->getAllowedPermissions($userType) & $permission) { + return true; + } + return false; + } + + /** + * @param string $userType + * @param int $permissions + * @return self + */ + public function setAllowedPermissions($userType, $permissions) { + $this->allowedPermissions[$userType] = $permissions; + $this->permissions[$userType] = + $this->getPermissions($userType) & $permissions; + return $this; + } + + /** + * @param string $userType + * @param int $permission + * @return self + */ + public function addAllowedPermission($userType, $permission) { + return $this->setAllowedPermissions($userType, + $this->getAllowedPermissions($userType) | $permission + ); + } + + /** + * @param string $userType + * @param int $permission + * @return self + */ + public function removeAllowedPermission($userType, $permission) { + return $this->setAllowedPermissions($userType, + $this->getAllowedPermissions($userType) & ~$permission + ); + } + +} diff --git a/apps/files_external/lib/visibilitytrait.php b/apps/files_external/lib/visibilitytrait.php deleted file mode 100644 index dfd2d323ca6..00000000000 --- a/apps/files_external/lib/visibilitytrait.php +++ /dev/null @@ -1,136 +0,0 @@ - - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Files_External\Lib; - -use \OCA\Files_External\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); - } - -} diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index 8717d91d4f1..d47f983b357 100644 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -34,8 +34,12 @@ $userStoragesService = $appContainer->query('OCA\Files_external\Service\UserStor OCP\Util::addScript('files_external', 'settings'); OCP\Util::addStyle('files_external', 'settings'); -$backends = $backendService->getBackendsVisibleFor(BackendService::VISIBILITY_PERSONAL); -$authMechanisms = $backendService->getAuthMechanismsVisibleFor(BackendService::VISIBILITY_PERSONAL); +$backends = array_filter($backendService->getAvailableBackends(), function($backend) { + return $backend->isPermitted(BackendService::USER_PERSONAL, BackendService::PERMISSION_CREATE); +}); +$authMechanisms = array_filter($backendService->getAuthMechanisms(), function($authMechanism) { + return $authMechanism->isPermitted(BackendService::USER_PERSONAL, BackendService::PERMISSION_CREATE); +}); foreach ($backends as $backend) { if ($backend->getCustomJs()) { \OCP\Util::addScript('files_external', $backend->getCustomJs()); diff --git a/apps/files_external/service/backendservice.php b/apps/files_external/service/backendservice.php index 382834b4c19..d9a3e316ce4 100644 --- a/apps/files_external/service/backendservice.php +++ b/apps/files_external/service/backendservice.php @@ -31,13 +31,16 @@ use \OCA\Files_External\Lib\Auth\AuthMechanism; */ class BackendService { - /** Visibility constants for VisibilityTrait */ - const VISIBILITY_NONE = 0; - const VISIBILITY_PERSONAL = 1; - const VISIBILITY_ADMIN = 2; - //const VISIBILITY_ALIENS = 4; + /** Permission constants for PermissionsTrait */ + const PERMISSION_NONE = 0; + const PERMISSION_MOUNT = 1; + const PERMISSION_CREATE = 2; - const VISIBILITY_DEFAULT = 3; // PERSONAL | ADMIN + const PERMISSION_DEFAULT = 3; // MOUNT | CREATE + + /** User contants */ + const USER_ADMIN = 'admin'; + const USER_PERSONAL = 'personal'; /** Priority constants for PriorityTrait */ const PRIORITY_DEFAULT = 100; @@ -81,7 +84,7 @@ class BackendService { */ public function registerBackend(Backend $backend) { if (!$this->isAllowedUserBackend($backend)) { - $backend->removeVisibility(BackendService::VISIBILITY_PERSONAL); + $backend->removePermission(self::USER_PERSONAL, self::PERMISSION_CREATE | self::PERMISSION_MOUNT); } foreach ($backend->getIdentifierAliases() as $alias) { $this->backends[$alias] = $backend; @@ -103,7 +106,7 @@ class BackendService { */ public function registerAuthMechanism(AuthMechanism $authMech) { if (!$this->isAllowedAuthMechanism($authMech)) { - $authMech->removeVisibility(BackendService::VISIBILITY_PERSONAL); + $authMech->removePermission(self::USER_PERSONAL, self::PERMISSION_CREATE | self::PERMISSION_MOUNT); } foreach ($authMech->getIdentifierAliases() as $alias) { $this->authMechanisms[$alias] = $authMech; @@ -144,30 +147,6 @@ class BackendService { }); } - /** - * 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 @@ -205,31 +184,6 @@ class BackendService { }); } - /** - * 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 diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index 29c0553158f..840f1325fb5 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -41,8 +41,12 @@ OCP\Util::addStyle('files_external', 'settings'); \OC_Util::addVendorScript('select2/select2'); \OC_Util::addVendorStyle('select2/select2'); -$backends = $backendService->getBackendsVisibleFor(BackendService::VISIBILITY_ADMIN); -$authMechanisms = $backendService->getAuthMechanismsVisibleFor(BackendService::VISIBILITY_ADMIN); +$backends = array_filter($backendService->getAvailableBackends(), function($backend) { + return $backend->isPermitted(BackendService::USER_ADMIN, BackendService::PERMISSION_CREATE); +}); +$authMechanisms = array_filter($backendService->getAuthMechanisms(), function($authMechanism) { + return $authMechanism->isPermitted(BackendService::USER_ADMIN, BackendService::PERMISSION_CREATE); +}); foreach ($backends as $backend) { if ($backend->getCustomJs()) { \OCP\Util::addScript('files_external', $backend->getCustomJs()); @@ -54,13 +58,19 @@ foreach ($authMechanisms as $authMechanism) { } } +$userBackends = array_filter($backendService->getAvailableBackends(), function($backend) { + return $backend->isAllowedPermitted( + BackendService::USER_PERSONAL, BackendService::PERMISSION_MOUNT + ); +}); + $tmpl = new OCP\Template('files_external', 'settings'); $tmpl->assign('encryptionEnabled', \OC::$server->getEncryptionManager()->isEnabled()); $tmpl->assign('isAdminPage', true); $tmpl->assign('storages', $globalStoragesService->getAllStorages()); $tmpl->assign('backends', $backends); $tmpl->assign('authMechanisms', $authMechanisms); -$tmpl->assign('userBackends', $backendService->getBackendsAllowedVisibleFor(BackendService::VISIBILITY_PERSONAL)); +$tmpl->assign('userBackends', $userBackends); $tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); $tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); return $tmpl->fetchPage(); diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index 5b79edf6cf7..63a3a19de2f 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -197,7 +197,7 @@

class="hidden"> t('Allow users to mount the following external storage')); ?>
- isVisibleFor(BackendService::VISIBILITY_PERSONAL)) print_unescaped(' checked="checked"'); ?> /> + isPermitted(BackendService::USER_PERSONAL, BackendService::PERMISSION_MOUNT)) print_unescaped(' checked="checked"'); ?> />
diff --git a/apps/files_external/tests/controller/storagescontrollertest.php b/apps/files_external/tests/controller/storagescontrollertest.php index 2b0ee7a14ea..5a2cff99244 100644 --- a/apps/files_external/tests/controller/storagescontrollertest.php +++ b/apps/files_external/tests/controller/storagescontrollertest.php @@ -78,7 +78,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $backend = $this->getBackendMock(); $backend->method('validateStorage') ->willReturn(true); - $backend->method('isVisibleFor') + $backend->method('isPermitted') ->willReturn(true); $storageConfig = new StorageConfig(1); @@ -117,7 +117,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $backend = $this->getBackendMock(); $backend->method('validateStorage') ->willReturn(true); - $backend->method('isVisibleFor') + $backend->method('isPermitted') ->willReturn(true); $storageConfig = new StorageConfig(1); @@ -248,7 +248,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $backend = $this->getBackendMock(); $backend->method('validateStorage') ->willReturn(true); - $backend->method('isVisibleFor') + $backend->method('isPermitted') ->willReturn(true); $storageConfig = new StorageConfig(255); @@ -332,7 +332,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $backend = $this->getBackendMock(); $backend->method('validateStorage') ->willReturn($backendValidate); - $backend->method('isVisibleFor') + $backend->method('isPermitted') ->willReturn(true); $authMech = $this->getAuthMechMock(); diff --git a/apps/files_external/tests/controller/userstoragescontrollertest.php b/apps/files_external/tests/controller/userstoragescontrollertest.php index 9f1a8df8d2e..b9668064e33 100644 --- a/apps/files_external/tests/controller/userstoragescontrollertest.php +++ b/apps/files_external/tests/controller/userstoragescontrollertest.php @@ -50,8 +50,8 @@ class UserStoragesControllerTest extends StoragesControllerTest { public function testAddOrUpdateStorageDisallowedBackend() { $backend = $this->getBackendMock(); - $backend->method('isVisibleFor') - ->with(BackendService::VISIBILITY_PERSONAL) + $backend->method('isPermitted') + ->with(BackendService::USER_PERSONAL, BackendService::PERMISSION_MOUNT) ->willReturn(false); $authMech = $this->getAuthMechMock(); diff --git a/apps/files_external/tests/service/backendservicetest.php b/apps/files_external/tests/service/backendservicetest.php index 08f6b9bf988..b37b5e9b466 100644 --- a/apps/files_external/tests/service/backendservicetest.php +++ b/apps/files_external/tests/service/backendservicetest.php @@ -83,11 +83,11 @@ class BackendServiceTest extends \Test\TestCase { $backendAllowed = $this->getBackendMock('\User\Mount\Allowed'); $backendAllowed->expects($this->never()) - ->method('removeVisibility'); + ->method('removePermission'); $backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed'); $backendNotAllowed->expects($this->once()) - ->method('removeVisibility') - ->with(BackendService::VISIBILITY_PERSONAL); + ->method('removePermission') + ->with(BackendService::USER_PERSONAL, BackendService::PERMISSION_CREATE | BackendService::PERMISSION_MOUNT); $backendAlias = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend') ->disableOriginalConstructor() @@ -126,27 +126,5 @@ class BackendServiceTest extends \Test\TestCase { $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); - } - } -- cgit v1.2.3 From 0b97a05e7bd631d66de1c2aee115113ada8a5f63 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Fri, 28 Aug 2015 16:16:48 +0100 Subject: Prevent creation of deprecated backends --- apps/files_external/lib/backend/sftp_key.php | 2 ++ apps/files_external/lib/backend/smb_oc.php | 2 ++ 2 files changed, 4 insertions(+) (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/lib/backend/sftp_key.php b/apps/files_external/lib/backend/sftp_key.php index 4a7f565eb19..6a75172026d 100644 --- a/apps/files_external/lib/backend/sftp_key.php +++ b/apps/files_external/lib/backend/sftp_key.php @@ -40,6 +40,8 @@ class SFTP_Key extends Backend { (new DefinitionParameter('root', $l->t('Remote subfolder'))) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]) + ->removeAllowedPermission(BackendService::USER_PERSONAL, BackendService::PERMISSION_CREATE) + ->removeAllowedPermission(BackendService::USER_ADMIN, BackendService::PERMISSION_CREATE) ->addAuthScheme(AuthMechanism::SCHEME_PUBLICKEY) ->setLegacyAuthMechanism($legacyAuth) ; diff --git a/apps/files_external/lib/backend/smb_oc.php b/apps/files_external/lib/backend/smb_oc.php index cae3818c76c..67fa8ffb2c4 100644 --- a/apps/files_external/lib/backend/smb_oc.php +++ b/apps/files_external/lib/backend/smb_oc.php @@ -49,6 +49,8 @@ class SMB_OC extends Backend { ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]) ->setDependencyCheck('\OC\Files\Storage\SMB::checkDependencies') + ->removeAllowedPermission(BackendService::USER_PERSONAL, BackendService::PERMISSION_CREATE) + ->removeAllowedPermission(BackendService::USER_ADMIN, BackendService::PERMISSION_CREATE) ->setPriority(BackendService::PRIORITY_DEFAULT - 10) ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) ->setLegacyAuthMechanism($legacyAuth) -- cgit v1.2.3 From e33d7b34fa14541b6d757e7cb2551870c939d15e Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Thu, 3 Sep 2015 09:39:14 +0100 Subject: Fix typo in SMB_OC --- apps/files_external/lib/backend/smb_oc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/lib/backend/smb_oc.php b/apps/files_external/lib/backend/smb_oc.php index 67fa8ffb2c4..3621682fb8f 100644 --- a/apps/files_external/lib/backend/smb_oc.php +++ b/apps/files_external/lib/backend/smb_oc.php @@ -58,9 +58,9 @@ class SMB_OC extends Backend { } public function manipulateStorageConfig(StorageConfig &$storage) { - $username_as_share = ($storage->getBackendOption('username_as_share') === 'true'); + $username_as_share = ($storage->getBackendOption('username_as_share') === true); - if ($this->username_as_share) { + if ($username_as_share) { $share = '/' . $storage->getBackendOption('user'); $storage->setBackendOption('share', $share); } -- cgit v1.2.3 From 442f5269ef229afa09cbe1e06b2a73bb9656e8c4 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Thu, 3 Sep 2015 09:50:45 +0100 Subject: Fix Swift legacy auth mechanism fallback --- apps/files_external/lib/backend/swift.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps/files_external/lib/backend') diff --git a/apps/files_external/lib/backend/swift.php b/apps/files_external/lib/backend/swift.php index 9f01a923638..c0ac7c08345 100644 --- a/apps/files_external/lib/backend/swift.php +++ b/apps/files_external/lib/backend/swift.php @@ -49,7 +49,7 @@ class Swift extends Backend { ->setDependencyCheck('\OC\Files\Storage\Swift::checkDependencies') ->addAuthScheme(AuthMechanism::SCHEME_OPENSTACK) ->setLegacyAuthMechanismCallback(function(array $params) use ($openstackAuth, $rackspaceAuth) { - if (isset($params['key'])) { + if (isset($params['options']['key']) && $params['options']['key']) { return $rackspaceAuth; } return $openstackAuth; -- cgit v1.2.3