Passed
Push — master ( a4b34a...debd32 )
by Morris
10:42 queued 10s
created
lib/private/Files/ObjectStore/SwiftFactory.php 1 patch
Indentation   +206 added lines, -206 removed lines patch added patch discarded remove patch
@@ -42,210 +42,210 @@
 block discarded – undo
42 42
 use OpenStack\ObjectStore\v1\Models\Container;
43 43
 
44 44
 class SwiftFactory {
45
-	private $cache;
46
-	private $params;
47
-	/** @var Container|null */
48
-	private $container = null;
49
-	private $logger;
50
-
51
-	const DEFAULT_OPTIONS = [
52
-		'autocreate' => false,
53
-		'urlType' => 'publicURL',
54
-		'catalogName' => 'swift',
55
-		'catalogType' => 'object-store'
56
-	];
57
-
58
-	public function __construct(ICache $cache, array $params, ILogger $logger) {
59
-		$this->cache = $cache;
60
-		$this->params = $params;
61
-		$this->logger = $logger;
62
-	}
63
-
64
-	private function getCachedToken(string $cacheKey) {
65
-		$cachedTokenString = $this->cache->get($cacheKey . '/token');
66
-		if ($cachedTokenString) {
67
-			return json_decode($cachedTokenString, true);
68
-		} else {
69
-			return null;
70
-		}
71
-	}
72
-
73
-	private function cacheToken(Token $token, string $serviceUrl, string $cacheKey) {
74
-		if ($token instanceof \OpenStack\Identity\v3\Models\Token) {
75
-			// for v3 the catalog is cached as part of the token, so no need to cache $serviceUrl separately
76
-			$value = json_encode($token->export());
77
-		} else {
78
-			/** @var \OpenStack\Identity\v2\Models\Token $token */
79
-			$value = json_encode([
80
-				'serviceUrl' => $serviceUrl,
81
-				'token' => [
82
-					'issued_at' => $token->issuedAt->format('c'),
83
-					'expires' => $token->expires->format('c'),
84
-					'id' => $token->id,
85
-					'tenant' => $token->tenant
86
-				]
87
-			]);
88
-		}
89
-		$this->cache->set($cacheKey . '/token', $value);
90
-	}
91
-
92
-	/**
93
-	 * @return OpenStack
94
-	 * @throws StorageAuthException
95
-	 */
96
-	private function getClient() {
97
-		if (isset($this->params['bucket'])) {
98
-			$this->params['container'] = $this->params['bucket'];
99
-		}
100
-		if (!isset($this->params['container'])) {
101
-			$this->params['container'] = 'nextcloud';
102
-		}
103
-		if (isset($this->params['user']) && is_array($this->params['user'])) {
104
-			$userName = $this->params['user']['name'];
105
-		} else {
106
-			if (!isset($this->params['username']) && isset($this->params['user'])) {
107
-				$this->params['username'] = $this->params['user'];
108
-			}
109
-			$userName = $this->params['username'];
110
-		}
111
-		if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) {
112
-			$this->params['tenantName'] = $this->params['tenant'];
113
-		}
114
-		$this->params = array_merge(self::DEFAULT_OPTIONS, $this->params);
115
-
116
-		$cacheKey = $userName . '@' . $this->params['url'] . '/' . $this->params['container'];
117
-		$token = $this->getCachedToken($cacheKey);
118
-		$this->params['cachedToken'] = $token;
119
-
120
-		$httpClient = new Client([
121
-			'base_uri' => TransportUtils::normalizeUrl($this->params['url']),
122
-			'handler' => HandlerStack::create()
123
-		]);
124
-
125
-		if (isset($this->params['user']) && is_array($this->params['user']) && isset($this->params['user']['name'])) {
126
-			if (!isset($this->params['scope'])) {
127
-				throw new StorageAuthException('Scope has to be defined for V3 requests');
128
-			}
129
-
130
-			return $this->auth(IdentityV3Service::factory($httpClient), $cacheKey);
131
-		} else {
132
-			return $this->auth(SwiftV2CachingAuthService::factory($httpClient), $cacheKey);
133
-		}
134
-	}
135
-
136
-	/**
137
-	 * @param IdentityV2Service|IdentityV3Service $authService
138
-	 * @param string $cacheKey
139
-	 * @return OpenStack
140
-	 * @throws StorageAuthException
141
-	 */
142
-	private function auth($authService, string $cacheKey) {
143
-		$this->params['identityService'] = $authService;
144
-		$this->params['authUrl'] = $this->params['url'];
145
-
146
-		$cachedToken = $this->params['cachedToken'];
147
-		$hasValidCachedToken = false;
148
-		if (\is_array($cachedToken)) {
149
-			if ($authService instanceof IdentityV3Service) {
150
-				$token = $authService->generateTokenFromCache($cachedToken);
151
-				if (\is_null($token->catalog)) {
152
-					$this->logger->warning('Invalid cached token for swift, no catalog set: ' . json_encode($cachedToken));
153
-				} else if ($token->hasExpired()) {
154
-					$this->logger->debug('Cached token for swift expired');
155
-				} else {
156
-					$hasValidCachedToken = true;
157
-				}
158
-			} else {
159
-				try {
160
-					/** @var \OpenStack\Identity\v2\Models\Token $token */
161
-					$token = $authService->model(\OpenStack\Identity\v2\Models\Token::class, $cachedToken['token']);
162
-					$now = new \DateTimeImmutable("now");
163
-					if ($token->expires > $now) {
164
-						$hasValidCachedToken = true;
165
-						$this->params['v2cachedToken'] = $token;
166
-						$this->params['v2serviceUrl'] = $cachedToken['serviceUrl'];
167
-					} else {
168
-						$this->logger->debug('Cached token for swift expired');
169
-					}
170
-				} catch (\Exception $e) {
171
-					$this->logger->logException($e);
172
-				}
173
-			}
174
-		}
175
-
176
-		if (!$hasValidCachedToken) {
177
-			unset($this->params['cachedToken']);
178
-			try {
179
-				list($token, $serviceUrl) = $authService->authenticate($this->params);
180
-				$this->cacheToken($token, $serviceUrl, $cacheKey);
181
-			} catch (ConnectException $e) {
182
-				throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e);
183
-			} catch (ClientException $e) {
184
-				$statusCode = $e->getResponse()->getStatusCode();
185
-				if ($statusCode === 404) {
186
-					throw new StorageAuthException('Keystone not found, verify the keystone url', $e);
187
-				} else if ($statusCode === 412) {
188
-					throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
189
-				} else if ($statusCode === 401) {
190
-					throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
191
-				} else {
192
-					throw new StorageAuthException('Unknown error', $e);
193
-				}
194
-			} catch (RequestException $e) {
195
-				throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e);
196
-			}
197
-		}
198
-
199
-
200
-		$client = new OpenStack($this->params);
201
-
202
-		return $client;
203
-	}
204
-
205
-	/**
206
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
207
-	 * @throws StorageAuthException
208
-	 * @throws StorageNotAvailableException
209
-	 */
210
-	public function getContainer() {
211
-		if (is_null($this->container)) {
212
-			$this->container = $this->createContainer();
213
-		}
214
-
215
-		return $this->container;
216
-	}
217
-
218
-	/**
219
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
220
-	 * @throws StorageAuthException
221
-	 * @throws StorageNotAvailableException
222
-	 */
223
-	private function createContainer() {
224
-		$client = $this->getClient();
225
-		$objectStoreService = $client->objectStoreV1();
226
-
227
-		$autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true;
228
-		try {
229
-			$container = $objectStoreService->getContainer($this->params['container']);
230
-			if ($autoCreate) {
231
-				$container->getMetadata();
232
-			}
233
-			return $container;
234
-		} catch (BadResponseError $ex) {
235
-			// if the container does not exist and autocreate is true try to create the container on the fly
236
-			if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) {
237
-				return $objectStoreService->createContainer([
238
-					'name' => $this->params['container']
239
-				]);
240
-			} else {
241
-				throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $ex);
242
-			}
243
-		} catch (ConnectException $e) {
244
-			/** @var RequestInterface $request */
245
-			$request = $e->getRequest();
246
-			$host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
247
-			\OC::$server->getLogger()->error("Can't connect to object storage server at $host");
248
-			throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
249
-		}
250
-	}
45
+    private $cache;
46
+    private $params;
47
+    /** @var Container|null */
48
+    private $container = null;
49
+    private $logger;
50
+
51
+    const DEFAULT_OPTIONS = [
52
+        'autocreate' => false,
53
+        'urlType' => 'publicURL',
54
+        'catalogName' => 'swift',
55
+        'catalogType' => 'object-store'
56
+    ];
57
+
58
+    public function __construct(ICache $cache, array $params, ILogger $logger) {
59
+        $this->cache = $cache;
60
+        $this->params = $params;
61
+        $this->logger = $logger;
62
+    }
63
+
64
+    private function getCachedToken(string $cacheKey) {
65
+        $cachedTokenString = $this->cache->get($cacheKey . '/token');
66
+        if ($cachedTokenString) {
67
+            return json_decode($cachedTokenString, true);
68
+        } else {
69
+            return null;
70
+        }
71
+    }
72
+
73
+    private function cacheToken(Token $token, string $serviceUrl, string $cacheKey) {
74
+        if ($token instanceof \OpenStack\Identity\v3\Models\Token) {
75
+            // for v3 the catalog is cached as part of the token, so no need to cache $serviceUrl separately
76
+            $value = json_encode($token->export());
77
+        } else {
78
+            /** @var \OpenStack\Identity\v2\Models\Token $token */
79
+            $value = json_encode([
80
+                'serviceUrl' => $serviceUrl,
81
+                'token' => [
82
+                    'issued_at' => $token->issuedAt->format('c'),
83
+                    'expires' => $token->expires->format('c'),
84
+                    'id' => $token->id,
85
+                    'tenant' => $token->tenant
86
+                ]
87
+            ]);
88
+        }
89
+        $this->cache->set($cacheKey . '/token', $value);
90
+    }
91
+
92
+    /**
93
+     * @return OpenStack
94
+     * @throws StorageAuthException
95
+     */
96
+    private function getClient() {
97
+        if (isset($this->params['bucket'])) {
98
+            $this->params['container'] = $this->params['bucket'];
99
+        }
100
+        if (!isset($this->params['container'])) {
101
+            $this->params['container'] = 'nextcloud';
102
+        }
103
+        if (isset($this->params['user']) && is_array($this->params['user'])) {
104
+            $userName = $this->params['user']['name'];
105
+        } else {
106
+            if (!isset($this->params['username']) && isset($this->params['user'])) {
107
+                $this->params['username'] = $this->params['user'];
108
+            }
109
+            $userName = $this->params['username'];
110
+        }
111
+        if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) {
112
+            $this->params['tenantName'] = $this->params['tenant'];
113
+        }
114
+        $this->params = array_merge(self::DEFAULT_OPTIONS, $this->params);
115
+
116
+        $cacheKey = $userName . '@' . $this->params['url'] . '/' . $this->params['container'];
117
+        $token = $this->getCachedToken($cacheKey);
118
+        $this->params['cachedToken'] = $token;
119
+
120
+        $httpClient = new Client([
121
+            'base_uri' => TransportUtils::normalizeUrl($this->params['url']),
122
+            'handler' => HandlerStack::create()
123
+        ]);
124
+
125
+        if (isset($this->params['user']) && is_array($this->params['user']) && isset($this->params['user']['name'])) {
126
+            if (!isset($this->params['scope'])) {
127
+                throw new StorageAuthException('Scope has to be defined for V3 requests');
128
+            }
129
+
130
+            return $this->auth(IdentityV3Service::factory($httpClient), $cacheKey);
131
+        } else {
132
+            return $this->auth(SwiftV2CachingAuthService::factory($httpClient), $cacheKey);
133
+        }
134
+    }
135
+
136
+    /**
137
+     * @param IdentityV2Service|IdentityV3Service $authService
138
+     * @param string $cacheKey
139
+     * @return OpenStack
140
+     * @throws StorageAuthException
141
+     */
142
+    private function auth($authService, string $cacheKey) {
143
+        $this->params['identityService'] = $authService;
144
+        $this->params['authUrl'] = $this->params['url'];
145
+
146
+        $cachedToken = $this->params['cachedToken'];
147
+        $hasValidCachedToken = false;
148
+        if (\is_array($cachedToken)) {
149
+            if ($authService instanceof IdentityV3Service) {
150
+                $token = $authService->generateTokenFromCache($cachedToken);
151
+                if (\is_null($token->catalog)) {
152
+                    $this->logger->warning('Invalid cached token for swift, no catalog set: ' . json_encode($cachedToken));
153
+                } else if ($token->hasExpired()) {
154
+                    $this->logger->debug('Cached token for swift expired');
155
+                } else {
156
+                    $hasValidCachedToken = true;
157
+                }
158
+            } else {
159
+                try {
160
+                    /** @var \OpenStack\Identity\v2\Models\Token $token */
161
+                    $token = $authService->model(\OpenStack\Identity\v2\Models\Token::class, $cachedToken['token']);
162
+                    $now = new \DateTimeImmutable("now");
163
+                    if ($token->expires > $now) {
164
+                        $hasValidCachedToken = true;
165
+                        $this->params['v2cachedToken'] = $token;
166
+                        $this->params['v2serviceUrl'] = $cachedToken['serviceUrl'];
167
+                    } else {
168
+                        $this->logger->debug('Cached token for swift expired');
169
+                    }
170
+                } catch (\Exception $e) {
171
+                    $this->logger->logException($e);
172
+                }
173
+            }
174
+        }
175
+
176
+        if (!$hasValidCachedToken) {
177
+            unset($this->params['cachedToken']);
178
+            try {
179
+                list($token, $serviceUrl) = $authService->authenticate($this->params);
180
+                $this->cacheToken($token, $serviceUrl, $cacheKey);
181
+            } catch (ConnectException $e) {
182
+                throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e);
183
+            } catch (ClientException $e) {
184
+                $statusCode = $e->getResponse()->getStatusCode();
185
+                if ($statusCode === 404) {
186
+                    throw new StorageAuthException('Keystone not found, verify the keystone url', $e);
187
+                } else if ($statusCode === 412) {
188
+                    throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
189
+                } else if ($statusCode === 401) {
190
+                    throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
191
+                } else {
192
+                    throw new StorageAuthException('Unknown error', $e);
193
+                }
194
+            } catch (RequestException $e) {
195
+                throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e);
196
+            }
197
+        }
198
+
199
+
200
+        $client = new OpenStack($this->params);
201
+
202
+        return $client;
203
+    }
204
+
205
+    /**
206
+     * @return \OpenStack\ObjectStore\v1\Models\Container
207
+     * @throws StorageAuthException
208
+     * @throws StorageNotAvailableException
209
+     */
210
+    public function getContainer() {
211
+        if (is_null($this->container)) {
212
+            $this->container = $this->createContainer();
213
+        }
214
+
215
+        return $this->container;
216
+    }
217
+
218
+    /**
219
+     * @return \OpenStack\ObjectStore\v1\Models\Container
220
+     * @throws StorageAuthException
221
+     * @throws StorageNotAvailableException
222
+     */
223
+    private function createContainer() {
224
+        $client = $this->getClient();
225
+        $objectStoreService = $client->objectStoreV1();
226
+
227
+        $autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true;
228
+        try {
229
+            $container = $objectStoreService->getContainer($this->params['container']);
230
+            if ($autoCreate) {
231
+                $container->getMetadata();
232
+            }
233
+            return $container;
234
+        } catch (BadResponseError $ex) {
235
+            // if the container does not exist and autocreate is true try to create the container on the fly
236
+            if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) {
237
+                return $objectStoreService->createContainer([
238
+                    'name' => $this->params['container']
239
+                ]);
240
+            } else {
241
+                throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $ex);
242
+            }
243
+        } catch (ConnectException $e) {
244
+            /** @var RequestInterface $request */
245
+            $request = $e->getRequest();
246
+            $host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
247
+            \OC::$server->getLogger()->error("Can't connect to object storage server at $host");
248
+            throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
249
+        }
250
+    }
251 251
 }
Please login to merge, or discard this patch.