diff options
-rw-r--r-- | .drone.yml | 4 | ||||
-rw-r--r-- | apps/files_external/lib/AppInfo/Application.php | 6 | ||||
-rw-r--r-- | apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php (renamed from apps/files_external/lib/Lib/Auth/OpenStack/OpenStack.php) | 4 | ||||
-rw-r--r-- | apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php | 49 | ||||
-rw-r--r-- | apps/files_external/lib/Lib/Backend/Swift.php | 5 | ||||
-rw-r--r-- | apps/files_external/lib/Lib/Storage/Swift.php | 15 | ||||
-rw-r--r-- | config/config.sample.php | 22 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/SwiftFactory.php | 34 | ||||
-rwxr-xr-x | tests/drone-wait-objectstore.sh | 7 | ||||
-rw-r--r-- | tests/preseed-config.php | 48 |
10 files changed, 166 insertions, 28 deletions
diff --git a/.drone.yml b/.drone.yml index 9a0e7b25484..896d385ca33 100644 --- a/.drone.yml +++ b/.drone.yml @@ -755,6 +755,10 @@ matrix: OBJECT_STORE: s3 - TESTS: object-store OBJECT_STORE: swift + SWIFT-AUTH: v2.0 + - TESTS: object-store + OBJECT_STORE: swift + SWIFT-AUTH: v3 - TESTS: sqlite-php7.0-samba-native - TESTS: sqlite-php7.0-samba-non-native - TEST: memcache-memcached diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php index e037b9b34e5..f312e065114 100644 --- a/apps/files_external/lib/AppInfo/Application.php +++ b/apps/files_external/lib/AppInfo/Application.php @@ -36,7 +36,8 @@ use \OCA\Files_External\Lib\Config\IBackendProvider; use \OCA\Files_External\Lib\Config\IAuthMechanismProvider; use OCA\Files_External\Lib\Auth\AmazonS3\AccessKey; use OCA\Files_External\Lib\Auth\OpenStack\Rackspace; -use OCA\Files_External\Lib\Auth\OpenStack\OpenStack; +use OCA\Files_External\Lib\Auth\OpenStack\OpenStackV2; +use OCA\Files_External\Lib\Auth\OpenStack\OpenStackV3; use OCA\Files_External\Lib\Auth\PublicKey\RSA; use OCA\Files_External\Lib\Auth\OAuth2\OAuth2; use OCA\Files_External\Lib\Auth\OAuth1\OAuth1; @@ -139,7 +140,8 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide $container->query(RSA::class), // AuthMechanism::SCHEME_OPENSTACK mechanisms - $container->query(OpenStack::class), + $container->query(OpenStackV2::class), + $container->query(OpenStackV3::class), $container->query(Rackspace::class), // Specialized mechanisms diff --git a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStack.php b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php index ca1e0a08ae9..f25918561f8 100644 --- a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStack.php +++ b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php @@ -29,13 +29,13 @@ use \OCA\Files_External\Lib\Auth\AuthMechanism; /** * OpenStack Keystone authentication */ -class OpenStack extends AuthMechanism { +class OpenStackV2 extends AuthMechanism { public function __construct(IL10N $l) { $this ->setIdentifier('openstack::openstack') ->setScheme(self::SCHEME_OPENSTACK) - ->setText($l->t('OpenStack')) + ->setText($l->t('OpenStack v2')) ->addParameters([ new DefinitionParameter('user', $l->t('Username')), (new DefinitionParameter('password', $l->t('Password'))) diff --git a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php new file mode 100644 index 00000000000..ead790e0ab5 --- /dev/null +++ b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php @@ -0,0 +1,49 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Files_External\Lib\Auth\OpenStack; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; + +/** + * OpenStack Keystone authentication + */ +class OpenStackV3 extends AuthMechanism { + + public function __construct(IL10N $l) { + $this + ->setIdentifier('openstack::openstackv3') + ->setScheme(self::SCHEME_OPENSTACK) + ->setText($l->t('OpenStack v3')) + ->addParameters([ + new DefinitionParameter('user', $l->t('Username')), + new DefinitionParameter('domain', $l->t('Domain')), + (new DefinitionParameter('password', $l->t('Password'))) + ->setType(DefinitionParameter::VALUE_PASSWORD), + new DefinitionParameter('url', $l->t('Identity endpoint URL')) + ]) + ; + } + +} diff --git a/apps/files_external/lib/Lib/Backend/Swift.php b/apps/files_external/lib/Lib/Backend/Swift.php index f2b694362f4..72fc236bcdc 100644 --- a/apps/files_external/lib/Lib/Backend/Swift.php +++ b/apps/files_external/lib/Lib/Backend/Swift.php @@ -25,7 +25,8 @@ namespace OCA\Files_External\Lib\Backend; use \OCP\IL10N; use \OCA\Files_External\Lib\DefinitionParameter; use \OCA\Files_External\Lib\Auth\AuthMechanism; -use \OCA\Files_External\Lib\Auth\OpenStack\OpenStack; +use \OCA\Files_External\Service\BackendService; +use \OCA\Files_External\Lib\Auth\OpenStack\OpenStackV2; use \OCA\Files_External\Lib\Auth\OpenStack\Rackspace; use \OCA\Files_External\Lib\LegacyDependencyCheckPolyfill; @@ -33,7 +34,7 @@ class Swift extends Backend { use LegacyDependencyCheckPolyfill; - public function __construct(IL10N $l, OpenStack $openstackAuth, Rackspace $rackspaceAuth) { + public function __construct(IL10N $l, OpenStackV2 $openstackAuth, Rackspace $rackspaceAuth) { $this ->setIdentifier('swift') ->addIdentifierAlias('\OC\Files\Storage\Swift') // legacy compat diff --git a/apps/files_external/lib/Lib/Storage/Swift.php b/apps/files_external/lib/Lib/Storage/Swift.php index 051c65350d5..a638169dcb2 100644 --- a/apps/files_external/lib/Lib/Storage/Swift.php +++ b/apps/files_external/lib/Lib/Storage/Swift.php @@ -156,13 +156,14 @@ class Swift extends \OC\Files\Storage\Common { public function __construct($params) { if ((empty($params['key']) and empty($params['password'])) - or empty($params['user']) or empty($params['bucket']) + or (empty($params['user']) && empty($params['userid'])) or empty($params['bucket']) or empty($params['region']) ) { throw new StorageBadConfigException("API Key or password, Username, Bucket and Region have to be configured."); } - $this->id = 'swift::' . $params['user'] . md5($params['bucket']); + $user = $params['user']; + $this->id = 'swift::' . $user . md5($params['bucket']); $bucketUrl = new Uri($params['bucket']); if ($bucketUrl->getHost()) { @@ -180,6 +181,16 @@ class Swift extends \OC\Files\Storage\Common { $params['autocreate'] = true; + if (isset($params['domain'])) { + $params['user'] = [ + 'name' => $params['user'], + 'password' => $params['password'], + 'domain' => [ + 'name' => $params['domain'], + ] + ]; + } + $this->params = $params; // FIXME: private class... $this->objectCache = new \OC\Cache\CappedMemoryCache(); diff --git a/config/config.sample.php b/config/config.sample.php index faeebb6fa8a..e91452a0720 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1214,6 +1214,28 @@ $CONFIG = array( ], ], +/** + * To use swift V3 + */ +'objectstore' => [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => [ + 'autocreate' => true, + 'user' => [ + 'name' => 'swift', + 'password' => 'swift', + 'domain' => [ + 'name' => 'default', + ] + ], + 'tenantName' => 'service', + 'serviceName' => 'swift', + 'region' => 'regionOne', + 'url' => "http://yourswifthost:5000/v3", + 'bucket' => 'nextcloud' + ], +], + /** * Sharing diff --git a/lib/private/Files/ObjectStore/SwiftFactory.php b/lib/private/Files/ObjectStore/SwiftFactory.php index 0df6fb6efcd..9513cdc3ab8 100644 --- a/lib/private/Files/ObjectStore/SwiftFactory.php +++ b/lib/private/Files/ObjectStore/SwiftFactory.php @@ -31,8 +31,9 @@ use OCP\Files\StorageAuthException; use OCP\Files\StorageNotAvailableException; use OCP\ICache; use OpenStack\Common\Error\BadResponseError; -use OpenStack\Identity\v2\Models\Token; -use OpenStack\Identity\v2\Service; +use OpenStack\Common\Auth\Token; +use OpenStack\Identity\v2\Service as IdentityV2Service; +use OpenStack\Identity\v3\Service as IdentityV3Service; use OpenStack\OpenStack; use OpenStack\Common\Transport\Utils as TransportUtils; use Psr\Http\Message\RequestInterface; @@ -77,30 +78,49 @@ class SwiftFactory { // should only be true for tests $this->params['autocreate'] = false; } - if (!isset($this->params['username']) && isset($this->params['user'])) { - $this->params['username'] = $this->params['user']; + if (isset($this->params['user']) && is_array($this->params['user'])) { + $userName = $this->params['user']['name']; + } else { + if (!isset($this->params['username']) && isset($this->params['user'])) { + $this->params['username'] = $this->params['user']; + } + $userName = $this->params['username']; } if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) { $this->params['tenantName'] = $this->params['tenant']; } - $cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket']; + $cacheKey = $userName . '@' . $this->params['url'] . '/' . $this->params['bucket']; $token = $this->getCachedToken($cacheKey); $hasToken = is_array($token) && (new \DateTimeImmutable($token['expires_at'])) > (new \DateTimeImmutable('now')); if ($hasToken) { $this->params['cachedToken'] = $token; } + $httpClient = new Client([ 'base_uri' => TransportUtils::normalizeUrl($this->params['url']), 'handler' => HandlerStack::create() ]); - $authService = Service::factory($httpClient); + if (isset($this->params['user']) && isset($this->params['user']['name'])) { + return $this->auth(IdentityV3Service::factory($httpClient), $cacheKey); + } else { + return $this->auth(IdentityV2Service::factory($httpClient), $cacheKey); + } + } + + /** + * @param IdentityV2Service|IdentityV3Service $authService + * @param string $cacheKey + * @return OpenStack + * @throws StorageAuthException + */ + private function auth($authService, string $cacheKey) { $this->params['identityService'] = $authService; $this->params['authUrl'] = $this->params['url']; $client = new OpenStack($this->params); - if (!$hasToken) { + if (!isset($this->params['cachedToken'])) { try { $token = $authService->generateToken($this->params); $this->cacheToken($token, $cacheKey); diff --git a/tests/drone-wait-objectstore.sh b/tests/drone-wait-objectstore.sh index 228accc3da9..7914d45bed1 100755 --- a/tests/drone-wait-objectstore.sh +++ b/tests/drone-wait-objectstore.sh @@ -44,6 +44,7 @@ if [ "$OBJECT_STORE" == "swift" ]; then echo "creating test file" + i=0 while [ 1 ] do sleep 2 @@ -54,6 +55,12 @@ if [ "$OBJECT_STORE" == "swift" ]; then then break fi + + i=$((i + 1)) + if [ "$i" == "20" ] + then + exit -1 + fi done echo "deleting test file" diff --git a/tests/preseed-config.php b/tests/preseed-config.php index 5fbdc565417..779868310dc 100644 --- a/tests/preseed-config.php +++ b/tests/preseed-config.php @@ -36,17 +36,39 @@ if (getenv('OBJECT_STORE') === 's3') { } if (getenv('OBJECT_STORE') === 'swift') { $swiftHost = getenv('DRONE') === 'true' ? 'dockswift' : 'localhost'; - $CONFIG['objectstore'] = [ - 'class' => 'OC\\Files\\ObjectStore\\Swift', - 'arguments' => array( - 'autocreate' => true, - 'username' => 'swift', - 'tenantName' => 'service', - 'password' => 'swift', - 'serviceName' => 'swift', - 'region' => 'regionOne', - 'url' => "http://$swiftHost:5000/v2.0", - 'bucket' => 'nextcloud' - ) - ]; + + if (getenv('SWIFT-AUTH') === 'v2.0') { + $CONFIG['objectstore'] = [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => array( + 'autocreate' => true, + 'username' => 'swift', + 'tenantName' => 'service', + 'password' => 'swift', + 'serviceName' => 'swift', + 'region' => 'regionOne', + 'url' => "http://$swiftHost:5000/v2.0", + 'bucket' => 'nextcloud' + ) + ]; + } else { + $CONFIG['objectstore'] = [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => array( + 'autocreate' => true, + 'user' => [ + 'name' => 'swift', + 'password' => 'swift', + 'domain' => [ + 'name' => 'default', + ] + ], + 'tenantName' => 'service', + 'serviceName' => 'swift', + 'region' => 'regionOne', + 'url' => "http://$swiftHost:5000/v3", + 'bucket' => 'nextcloud' + ) + ]; + } } |