Skip to content

Commit

Permalink
Resolves #19790, Provides Support for IAM Credentials
Browse files Browse the repository at this point in the history
Includes support for either leveraging environment variables
passed to the PHP runtime or IAM instance profile present
on the host being used. The default and first choice is
still the parameter file as documented.

See also: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_provider.html#chaining-providers

Signed-off-by: Stephen Cuppett <steve@cuppett.com>
  • Loading branch information
cuppett authored and kesselb committed Aug 31, 2020
1 parent f48f7fe commit cb678cc
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions lib/private/Files/ObjectStore/S3ConnectionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
* @author S. Cat <33800996+sparrowjack63@users.noreply.github.com>
* @author Stephen Cuppett <steve@cuppett.com>
*
* @license GNU AGPL version 3 or any later version
*
Expand All @@ -28,8 +29,13 @@
namespace OC\Files\ObjectStore;

use Aws\ClientResolver;
use Aws\Credentials\CredentialProvider;
use Aws\Credentials\Credentials;
use Aws\Exception\CredentialsException;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Promise\RejectedPromise;
use OCP\ILogger;

trait S3ConnectionTrait {
Expand All @@ -54,8 +60,8 @@ trait S3ConnectionTrait {
protected $test;

protected function parseParams($params) {
if (empty($params['key']) || empty($params['secret']) || empty($params['bucket'])) {
throw new \Exception("Access Key, Secret and Bucket have to be configured.");
if (empty($params['bucket'])) {
throw new \Exception("Bucket has to be configured.");
}

$this->id = 'amazon::' . $params['bucket'];
Expand Down Expand Up @@ -90,12 +96,19 @@ public function getConnection() {
$scheme = (isset($this->params['use_ssl']) && $this->params['use_ssl'] === false) ? 'http' : 'https';
$base_url = $scheme . '://' . $this->params['hostname'] . ':' . $this->params['port'] . '/';

// Adding explicit credential provider to the beginning chain.
// Including environment variables and IAM instance profiles.
$provider = CredentialProvider::memoize(
CredentialProvider::chain(
$this->paramCredentialProvider(),
CredentialProvider::env(),
CredentialProvider::instanceProfile()
)
);

$options = [
'version' => isset($this->params['version']) ? $this->params['version'] : 'latest',
'credentials' => [
'key' => $this->params['key'],
'secret' => $this->params['secret'],
],
'credentials' => $provider,
'endpoint' => $base_url,
'region' => $this->params['region'],
'use_path_style_endpoint' => isset($this->params['use_path_style']) ? $this->params['use_path_style'] : false,
Expand Down Expand Up @@ -161,4 +174,23 @@ public static function legacySignatureProvider($version, $service, $region) {
return null;
}
}

/**
* This function creates a credential provider based on user parameter file
*/
protected function paramCredentialProvider() : callable {
return function () {
$key = empty($this->params['key']) ? null : $this->params['key'];
$secret = empty($this->params['secret']) ? null : $this->params['secret'];

if ($key && $secret) {
return Promise\promise_for(
new Credentials($key, $secret)
);
}

$msg = 'Could not find parameters set for credentials in config file.';
return new RejectedPromise(new CredentialsException($msg));
};
}
}

0 comments on commit cb678cc

Please sign in to comment.