Completed
Pull Request — master (#9092)
by Morris
21:07 queued 03:34
created

S3ConnectionTrait   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 114
rs 10
wmc 28
lcom 1
cbo 4

4 Methods

Rating   Name   Duplication   Size   Complexity  
B parseParams() 0 17 11
D getConnection() 0 51 12
A testTimeout() 0 5 2
A legacySignatureProvider() 0 9 3
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Robin Appelman <[email protected]>
4
 *
5
 * @author Morris Jobke <[email protected]>
6
 * @author Robin Appelman <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
25
namespace OC\Files\ObjectStore;
26
27
use Aws\ClientResolver;
28
use Aws\S3\Exception\S3Exception;
29
use Aws\S3\S3Client;
30
31
trait S3ConnectionTrait {
32
	/** @var array */
33
	protected $params;
34
35
	/** @var S3Client */
36
	protected $connection;
37
38
	/** @var string */
39
	protected $id;
40
41
	/** @var string */
42
	protected $bucket;
43
44
	/** @var int */
45
	protected $timeout;
46
47
	protected $test;
48
49
	protected function parseParams($params) {
50
		if (empty($params['key']) || empty($params['secret']) || empty($params['bucket'])) {
51
			throw new \Exception("Access Key, Secret and Bucket have to be configured.");
52
		}
53
54
		$this->id = 'amazon::' . $params['bucket'];
55
56
		$this->test = isset($params['test']);
57
		$this->bucket = $params['bucket'];
58
		$this->timeout = !isset($params['timeout']) ? 15 : $params['timeout'];
59
		$params['region'] = empty($params['region']) ? 'eu-west-1' : $params['region'];
60
		$params['hostname'] = empty($params['hostname']) ? 's3.' . $params['region'] . '.amazonaws.com' : $params['hostname'];
61
		if (!isset($params['port']) || $params['port'] === '') {
62
			$params['port'] = (isset($params['use_ssl']) && $params['use_ssl'] === false) ? 80 : 443;
63
		}
64
		$this->params = $params;
65
	}
66
67
68
	/**
69
	 * Returns the connection
70
	 *
71
	 * @return S3Client connected client
72
	 * @throws \Exception if connection could not be made
73
	 */
74
	protected function getConnection() {
75
		if (!is_null($this->connection)) {
76
			return $this->connection;
77
		}
78
79
		$scheme = (isset($this->params['use_ssl']) && $this->params['use_ssl'] === false) ? 'http' : 'https';
80
		$base_url = $scheme . '://' . $this->params['hostname'] . ':' . $this->params['port'] . '/';
81
82
		$options = [
83
			'version' => isset($this->params['version']) ? $this->params['version'] : 'latest',
84
			'credentials' => [
85
				'key' => $this->params['key'],
86
				'secret' => $this->params['secret'],
87
			],
88
			'endpoint' => $base_url,
89
			'region' => $this->params['region'],
90
			'use_path_style_endpoint' => isset($this->params['use_path_style']) ? $this->params['use_path_style'] : false,
91
			'signature_provider' => \Aws\or_chain([self::class, 'legacySignatureProvider'], ClientResolver::_default_signature_provider())
92
		];
93
		if (isset($this->params['proxy'])) {
94
			$options['request.options'] = ['proxy' => $this->params['proxy']];
95
		}
96
		if (isset($this->params['legacy_auth']) && $this->params['legacy_auth']) {
97
			$options['signature_version'] = 'v2';
98
		}
99
		$this->connection = new S3Client($options);
100
101
		if (!$this->connection->isBucketDnsCompatible($this->bucket)) {
102
			throw new \Exception("The configured bucket name is invalid: " . $this->bucket);
103
		}
104
105
		if (!$this->connection->doesBucketExist($this->bucket)) {
106
			$logger = \OC::$server->getLogger();
107
			try {
108
				$logger->info('Bucket "' . $this->bucket . '" does not exist - creating it.', ['app' => 'objectstore']);
109
				$this->connection->createBucket(array(
110
					'Bucket' => $this->bucket
111
				));
112
				$this->testTimeout();
113
			} catch (S3Exception $e) {
0 ignored issues
show
Bug introduced by
The class Aws\S3\Exception\S3Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
114
				$logger->logException($e, [
115
					'message' => 'Invalid remote storage.',
116
					'level' => \OCP\Util::DEBUG,
117
					'app' => 'objectstore',
118
				]);
119
				throw new \Exception('Creation of bucket "' . $this->bucket . '" failed. ' . $e->getMessage());
120
			}
121
		}
122
123
		return $this->connection;
124
	}
125
126
	/**
127
	 * when running the tests wait to let the buckets catch up
128
	 */
129
	private function testTimeout() {
130
		if ($this->test) {
131
			sleep($this->timeout);
132
		}
133
	}
134
135
	public static function legacySignatureProvider($version, $service, $region) {
0 ignored issues
show
Unused Code introduced by
The parameter $service is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $region is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
136
		switch ($version) {
137
			case 'v2':
138
			case 's3':
139
				return new S3Signature();
140
			default:
141
				return null;
142
		}
143
	}
144
}
145