Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions apps/files_external/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
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;
Expand Down Expand Up @@ -139,7 +140,8 @@ public function getAuthMechanisms() {
$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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
/**
* 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')))
Expand Down
49 changes: 49 additions & 0 deletions apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php
Original file line number Diff line number Diff line change
@@ -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'))
])
;
}

}
5 changes: 3 additions & 2 deletions apps/files_external/lib/Lib/Backend/Swift.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@
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;

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
Expand Down
15 changes: 13 additions & 2 deletions apps/files_external/lib/Lib/Storage/Swift.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,14 @@ private function doesObjectExist($path) {

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()) {
Expand All @@ -180,6 +181,16 @@ public function __construct($params) {

$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();
Expand Down
22 changes: 22 additions & 0 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,28 @@
],
],

/**
* To use swift V3
*/
'objectstore' => [
'class' => 'OC\\Files\\ObjectStore\\Swift',
'arguments' => [
'autocreate' => true,
'user' => [
'name' => 'swift',
'password' => 'swift',
'domain' => [
'name' => 'default',
]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rullzer missing comma?

Copy link
Copy Markdown
Member

@MorrisJobke MorrisJobke Mar 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is optional for the last element of an array (we usually add it to make the possible diff better readable).

],
'tenantName' => 'service',
'serviceName' => 'swift',
'region' => 'regionOne',
'url' => "http://yourswifthost:5000/v3",
'bucket' => 'nextcloud'
],
],


/**
* Sharing
Expand Down
34 changes: 27 additions & 7 deletions lib/private/Files/ObjectStore/SwiftFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
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;
Expand Down Expand Up @@ -77,30 +78,49 @@ private function getClient() {
// 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);
Expand Down
7 changes: 7 additions & 0 deletions tests/drone-wait-objectstore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ if [ "$OBJECT_STORE" == "swift" ]; then

echo "creating test file"

i=0
while [ 1 ]
do
sleep 2
Expand All @@ -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"
Expand Down
48 changes: 35 additions & 13 deletions tests/preseed-config.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,39 @@
}
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'
)
];
}
}