Passed
Push — master ( f4d909...6dc21f )
by Morris
30:39 queued 17:50
created
lib/private/Files/ObjectStore/SwiftFactory.php 1 patch
Indentation   +205 added lines, -205 removed lines patch added patch discarded remove patch
@@ -42,209 +42,209 @@
 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
-			try {
178
-				list($token, $serviceUrl) = $authService->authenticate($this->params);
179
-				$this->cacheToken($token, $serviceUrl, $cacheKey);
180
-			} catch (ConnectException $e) {
181
-				throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e);
182
-			} catch (ClientException $e) {
183
-				$statusCode = $e->getResponse()->getStatusCode();
184
-				if ($statusCode === 404) {
185
-					throw new StorageAuthException('Keystone not found, verify the keystone url', $e);
186
-				} else if ($statusCode === 412) {
187
-					throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
188
-				} else if ($statusCode === 401) {
189
-					throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
190
-				} else {
191
-					throw new StorageAuthException('Unknown error', $e);
192
-				}
193
-			} catch (RequestException $e) {
194
-				throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e);
195
-			}
196
-		}
197
-
198
-
199
-		$client = new OpenStack($this->params);
200
-
201
-		return $client;
202
-	}
203
-
204
-	/**
205
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
206
-	 * @throws StorageAuthException
207
-	 * @throws StorageNotAvailableException
208
-	 */
209
-	public function getContainer() {
210
-		if (is_null($this->container)) {
211
-			$this->container = $this->createContainer();
212
-		}
213
-
214
-		return $this->container;
215
-	}
216
-
217
-	/**
218
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
219
-	 * @throws StorageAuthException
220
-	 * @throws StorageNotAvailableException
221
-	 */
222
-	private function createContainer() {
223
-		$client = $this->getClient();
224
-		$objectStoreService = $client->objectStoreV1();
225
-
226
-		$autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true;
227
-		try {
228
-			$container = $objectStoreService->getContainer($this->params['container']);
229
-			if ($autoCreate) {
230
-				$container->getMetadata();
231
-			}
232
-			return $container;
233
-		} catch (BadResponseError $ex) {
234
-			// if the container does not exist and autocreate is true try to create the container on the fly
235
-			if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) {
236
-				return $objectStoreService->createContainer([
237
-					'name' => $this->params['container']
238
-				]);
239
-			} else {
240
-				throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $ex);
241
-			}
242
-		} catch (ConnectException $e) {
243
-			/** @var RequestInterface $request */
244
-			$request = $e->getRequest();
245
-			$host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
246
-			\OC::$server->getLogger()->error("Can't connect to object storage server at $host");
247
-			throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
248
-		}
249
-	}
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
+            try {
178
+                list($token, $serviceUrl) = $authService->authenticate($this->params);
179
+                $this->cacheToken($token, $serviceUrl, $cacheKey);
180
+            } catch (ConnectException $e) {
181
+                throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e);
182
+            } catch (ClientException $e) {
183
+                $statusCode = $e->getResponse()->getStatusCode();
184
+                if ($statusCode === 404) {
185
+                    throw new StorageAuthException('Keystone not found, verify the keystone url', $e);
186
+                } else if ($statusCode === 412) {
187
+                    throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
188
+                } else if ($statusCode === 401) {
189
+                    throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
190
+                } else {
191
+                    throw new StorageAuthException('Unknown error', $e);
192
+                }
193
+            } catch (RequestException $e) {
194
+                throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e);
195
+            }
196
+        }
197
+
198
+
199
+        $client = new OpenStack($this->params);
200
+
201
+        return $client;
202
+    }
203
+
204
+    /**
205
+     * @return \OpenStack\ObjectStore\v1\Models\Container
206
+     * @throws StorageAuthException
207
+     * @throws StorageNotAvailableException
208
+     */
209
+    public function getContainer() {
210
+        if (is_null($this->container)) {
211
+            $this->container = $this->createContainer();
212
+        }
213
+
214
+        return $this->container;
215
+    }
216
+
217
+    /**
218
+     * @return \OpenStack\ObjectStore\v1\Models\Container
219
+     * @throws StorageAuthException
220
+     * @throws StorageNotAvailableException
221
+     */
222
+    private function createContainer() {
223
+        $client = $this->getClient();
224
+        $objectStoreService = $client->objectStoreV1();
225
+
226
+        $autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true;
227
+        try {
228
+            $container = $objectStoreService->getContainer($this->params['container']);
229
+            if ($autoCreate) {
230
+                $container->getMetadata();
231
+            }
232
+            return $container;
233
+        } catch (BadResponseError $ex) {
234
+            // if the container does not exist and autocreate is true try to create the container on the fly
235
+            if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) {
236
+                return $objectStoreService->createContainer([
237
+                    'name' => $this->params['container']
238
+                ]);
239
+            } else {
240
+                throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $ex);
241
+            }
242
+        } catch (ConnectException $e) {
243
+            /** @var RequestInterface $request */
244
+            $request = $e->getRequest();
245
+            $host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
246
+            \OC::$server->getLogger()->error("Can't connect to object storage server at $host");
247
+            throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
248
+        }
249
+    }
250 250
 }
Please login to merge, or discard this patch.