Completed
Pull Request — master (#5042)
by Robin
18:55
created
apps/files_external/lib/Service/DBConfigService.php 1 patch
Indentation   +452 added lines, -452 removed lines patch added patch discarded remove patch
@@ -32,456 +32,456 @@
 block discarded – undo
32 32
  * Stores the mount config in the database
33 33
  */
34 34
 class DBConfigService {
35
-	const MOUNT_TYPE_ADMIN = 1;
36
-	const MOUNT_TYPE_PERSONAl = 2;
37
-
38
-	const APPLICABLE_TYPE_GLOBAL = 1;
39
-	const APPLICABLE_TYPE_GROUP = 2;
40
-	const APPLICABLE_TYPE_USER = 3;
41
-
42
-	/**
43
-	 * @var IDBConnection
44
-	 */
45
-	private $connection;
46
-
47
-	/**
48
-	 * @var ICrypto
49
-	 */
50
-	private $crypto;
51
-
52
-	/**
53
-	 * DBConfigService constructor.
54
-	 *
55
-	 * @param IDBConnection $connection
56
-	 * @param ICrypto $crypto
57
-	 */
58
-	public function __construct(IDBConnection $connection, ICrypto $crypto) {
59
-		$this->connection = $connection;
60
-		$this->crypto = $crypto;
61
-	}
62
-
63
-	/**
64
-	 * @param int $mountId
65
-	 * @return array
66
-	 */
67
-	public function getMountById($mountId) {
68
-		$builder = $this->connection->getQueryBuilder();
69
-		$query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
70
-			->from('external_mounts', 'm')
71
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
72
-		$mounts = $this->getMountsFromQuery($query);
73
-		if (count($mounts) > 0) {
74
-			return $mounts[0];
75
-		} else {
76
-			return null;
77
-		}
78
-	}
79
-
80
-	/**
81
-	 * Get all configured mounts
82
-	 *
83
-	 * @return array
84
-	 */
85
-	public function getAllMounts() {
86
-		$builder = $this->connection->getQueryBuilder();
87
-		$query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
88
-			->from('external_mounts');
89
-		return $this->getMountsFromQuery($query);
90
-	}
91
-
92
-	public function getMountsForUser($userId, $groupIds) {
93
-		$builder = $this->connection->getQueryBuilder();
94
-		$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
95
-			->from('external_mounts', 'm')
96
-			->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
97
-			->where($builder->expr()->orX(
98
-				$builder->expr()->andX( // global mounts
99
-					$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GLOBAL, IQueryBuilder::PARAM_INT)),
100
-					$builder->expr()->isNull('a.value')
101
-				),
102
-				$builder->expr()->andX( // mounts for user
103
-					$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_USER, IQueryBuilder::PARAM_INT)),
104
-					$builder->expr()->eq('a.value', $builder->createNamedParameter($userId))
105
-				),
106
-				$builder->expr()->andX( // mounts for group
107
-					$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GROUP, IQueryBuilder::PARAM_INT)),
108
-					$builder->expr()->in('a.value', $builder->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY))
109
-				)
110
-			));
111
-
112
-		return $this->getMountsFromQuery($query);
113
-	}
114
-
115
-	/**
116
-	 * Get admin defined mounts
117
-	 *
118
-	 * @return array
119
-	 */
120
-	public function getAdminMounts() {
121
-		$builder = $this->connection->getQueryBuilder();
122
-		$query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
123
-			->from('external_mounts')
124
-			->where($builder->expr()->eq('type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT)));
125
-		return $this->getMountsFromQuery($query);
126
-	}
127
-
128
-	protected function getForQuery(IQueryBuilder $builder, $type, $value) {
129
-		$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
130
-			->from('external_mounts', 'm')
131
-			->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
132
-			->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)));
133
-
134
-		if (is_null($value)) {
135
-			$query = $query->andWhere($builder->expr()->isNull('a.value'));
136
-		} else {
137
-			$query = $query->andWhere($builder->expr()->eq('a.value', $builder->createNamedParameter($value)));
138
-		}
139
-
140
-		return $query;
141
-	}
142
-
143
-	/**
144
-	 * Get mounts by applicable
145
-	 *
146
-	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
147
-	 * @param string|null $value user_id, group_id or null for global mounts
148
-	 * @return array
149
-	 */
150
-	public function getMountsFor($type, $value) {
151
-		$builder = $this->connection->getQueryBuilder();
152
-		$query = $this->getForQuery($builder, $type, $value);
153
-
154
-		return $this->getMountsFromQuery($query);
155
-	}
156
-
157
-	/**
158
-	 * Get admin defined mounts by applicable
159
-	 *
160
-	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
161
-	 * @param string|null $value user_id, group_id or null for global mounts
162
-	 * @return array
163
-	 */
164
-	public function getAdminMountsFor($type, $value) {
165
-		$builder = $this->connection->getQueryBuilder();
166
-		$query = $this->getForQuery($builder, $type, $value);
167
-		$query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT)));
168
-
169
-		return $this->getMountsFromQuery($query);
170
-	}
171
-
172
-	/**
173
-	 * Get admin defined mounts for multiple applicable
174
-	 *
175
-	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
176
-	 * @param string[] $values user_ids or group_ids
177
-	 * @return array
178
-	 */
179
-	public function getAdminMountsForMultiple($type, array $values) {
180
-		$builder = $this->connection->getQueryBuilder();
181
-		$params = array_map(function ($value) use ($builder) {
182
-			return $builder->createNamedParameter($value, IQueryBuilder::PARAM_STR);
183
-		}, $values);
184
-
185
-		$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
186
-			->from('external_mounts', 'm')
187
-			->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
188
-			->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)))
189
-			->andWhere($builder->expr()->in('a.value', $params));
190
-		$query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT)));
191
-
192
-		return $this->getMountsFromQuery($query);
193
-	}
194
-
195
-	/**
196
-	 * Get user defined mounts by applicable
197
-	 *
198
-	 * @param int $type any of the self::APPLICABLE_TYPE_ constants
199
-	 * @param string|null $value user_id, group_id or null for global mounts
200
-	 * @return array
201
-	 */
202
-	public function getUserMountsFor($type, $value) {
203
-		$builder = $this->connection->getQueryBuilder();
204
-		$query = $this->getForQuery($builder, $type, $value);
205
-		$query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_PERSONAl, IQueryBuilder::PARAM_INT)));
206
-
207
-		return $this->getMountsFromQuery($query);
208
-	}
209
-
210
-	/**
211
-	 * Add a mount to the database
212
-	 *
213
-	 * @param string $mountPoint
214
-	 * @param string $storageBackend
215
-	 * @param string $authBackend
216
-	 * @param int $priority
217
-	 * @param int $type self::MOUNT_TYPE_ADMIN or self::MOUNT_TYPE_PERSONAL
218
-	 * @return int the id of the new mount
219
-	 */
220
-	public function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
221
-		if (!$priority) {
222
-			$priority = 100;
223
-		}
224
-		$builder = $this->connection->getQueryBuilder();
225
-		$query = $builder->insert('external_mounts')
226
-			->values([
227
-				'mount_point' => $builder->createNamedParameter($mountPoint, IQueryBuilder::PARAM_STR),
228
-				'storage_backend' => $builder->createNamedParameter($storageBackend, IQueryBuilder::PARAM_STR),
229
-				'auth_backend' => $builder->createNamedParameter($authBackend, IQueryBuilder::PARAM_STR),
230
-				'priority' => $builder->createNamedParameter($priority, IQueryBuilder::PARAM_INT),
231
-				'type' => $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)
232
-			]);
233
-		$query->execute();
234
-		return (int)$this->connection->lastInsertId('*PREFIX*external_mounts');
235
-	}
236
-
237
-	/**
238
-	 * Remove a mount from the database
239
-	 *
240
-	 * @param int $mountId
241
-	 */
242
-	public function removeMount($mountId) {
243
-		$builder = $this->connection->getQueryBuilder();
244
-		$query = $builder->delete('external_mounts')
245
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
246
-		$query->execute();
247
-
248
-		$query = $builder->delete('external_applicable')
249
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
250
-		$query->execute();
251
-
252
-		$query = $builder->delete('external_config')
253
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
254
-		$query->execute();
255
-
256
-		$query = $builder->delete('external_options')
257
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
258
-		$query->execute();
259
-	}
260
-
261
-	/**
262
-	 * @param int $mountId
263
-	 * @param string $newMountPoint
264
-	 */
265
-	public function setMountPoint($mountId, $newMountPoint) {
266
-		$builder = $this->connection->getQueryBuilder();
267
-
268
-		$query = $builder->update('external_mounts')
269
-			->set('mount_point', $builder->createNamedParameter($newMountPoint))
270
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
271
-
272
-		$query->execute();
273
-	}
274
-
275
-	/**
276
-	 * @param int $mountId
277
-	 * @param string $newAuthBackend
278
-	 */
279
-	public function setAuthBackend($mountId, $newAuthBackend) {
280
-		$builder = $this->connection->getQueryBuilder();
281
-
282
-		$query = $builder->update('external_mounts')
283
-			->set('auth_backend', $builder->createNamedParameter($newAuthBackend))
284
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
285
-
286
-		$query->execute();
287
-	}
288
-
289
-	/**
290
-	 * @param int $mountId
291
-	 * @param string $key
292
-	 * @param string $value
293
-	 */
294
-	public function setConfig($mountId, $key, $value) {
295
-		if ($key === 'password') {
296
-			$value = $this->encryptValue($value);
297
-		}
298
-		$count = $this->connection->insertIfNotExist('*PREFIX*external_config', [
299
-			'mount_id' => $mountId,
300
-			'key' => $key,
301
-			'value' => $value
302
-		], ['mount_id', 'key']);
303
-		if ($count === 0) {
304
-			$builder = $this->connection->getQueryBuilder();
305
-			$query = $builder->update('external_config')
306
-				->set('value', $builder->createNamedParameter($value, IQueryBuilder::PARAM_STR))
307
-				->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
308
-				->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, IQueryBuilder::PARAM_STR)));
309
-			$query->execute();
310
-		}
311
-	}
312
-
313
-	/**
314
-	 * @param int $mountId
315
-	 * @param string $key
316
-	 * @param string $value
317
-	 */
318
-	public function setOption($mountId, $key, $value) {
319
-
320
-		$count = $this->connection->insertIfNotExist('*PREFIX*external_options', [
321
-			'mount_id' => $mountId,
322
-			'key' => $key,
323
-			'value' => json_encode($value)
324
-		], ['mount_id', 'key']);
325
-		if ($count === 0) {
326
-			$builder = $this->connection->getQueryBuilder();
327
-			$query = $builder->update('external_options')
328
-				->set('value', $builder->createNamedParameter(json_encode($value), IQueryBuilder::PARAM_STR))
329
-				->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
330
-				->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, IQueryBuilder::PARAM_STR)));
331
-			$query->execute();
332
-		}
333
-	}
334
-
335
-	public function addApplicable($mountId, $type, $value) {
336
-		$this->connection->insertIfNotExist('*PREFIX*external_applicable', [
337
-			'mount_id' => $mountId,
338
-			'type' => $type,
339
-			'value' => $value
340
-		], ['mount_id', 'type', 'value']);
341
-	}
342
-
343
-	public function removeApplicable($mountId, $type, $value) {
344
-		$builder = $this->connection->getQueryBuilder();
345
-		$query = $builder->delete('external_applicable')
346
-			->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
347
-			->andWhere($builder->expr()->eq('type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)));
348
-
349
-		if (is_null($value)) {
350
-			$query = $query->andWhere($builder->expr()->isNull('value'));
351
-		} else {
352
-			$query = $query->andWhere($builder->expr()->eq('value', $builder->createNamedParameter($value, IQueryBuilder::PARAM_STR)));
353
-		}
354
-
355
-		$query->execute();
356
-	}
357
-
358
-	private function getMountsFromQuery(IQueryBuilder $query) {
359
-		$result = $query->execute();
360
-		$mounts = $result->fetchAll();
361
-		$uniqueMounts = [];
362
-		foreach ($mounts as $mount) {
363
-			$id = $mount['mount_id'];
364
-			if (!isset($uniqueMounts[$id])) {
365
-				$uniqueMounts[$id] = $mount;
366
-			}
367
-		}
368
-		$uniqueMounts = array_values($uniqueMounts);
369
-
370
-		$mountIds = array_map(function ($mount) {
371
-			return $mount['mount_id'];
372
-		}, $uniqueMounts);
373
-		$mountIds = array_values(array_unique($mountIds));
374
-
375
-		$applicable = $this->getApplicableForMounts($mountIds);
376
-		$config = $this->getConfigForMounts($mountIds);
377
-		$options = $this->getOptionsForMounts($mountIds);
378
-
379
-		return array_map(function ($mount, $applicable, $config, $options) {
380
-			$mount['type'] = (int)$mount['type'];
381
-			$mount['priority'] = (int)$mount['priority'];
382
-			$mount['applicable'] = $applicable;
383
-			$mount['config'] = $config;
384
-			$mount['options'] = $options;
385
-			return $mount;
386
-		}, $uniqueMounts, $applicable, $config, $options);
387
-	}
388
-
389
-	/**
390
-	 * Get mount options from a table grouped by mount id
391
-	 *
392
-	 * @param string $table
393
-	 * @param string[] $fields
394
-	 * @param int[] $mountIds
395
-	 * @return array [$mountId => [['field1' => $value1, ...], ...], ...]
396
-	 */
397
-	private function selectForMounts($table, array $fields, array $mountIds) {
398
-		if (count($mountIds) === 0) {
399
-			return [];
400
-		}
401
-		$builder = $this->connection->getQueryBuilder();
402
-		$fields[] = 'mount_id';
403
-		$placeHolders = array_map(function ($id) use ($builder) {
404
-			return $builder->createPositionalParameter($id, IQueryBuilder::PARAM_INT);
405
-		}, $mountIds);
406
-		$query = $builder->select($fields)
407
-			->from($table)
408
-			->where($builder->expr()->in('mount_id', $placeHolders));
409
-		$rows = $query->execute()->fetchAll();
410
-
411
-		$result = [];
412
-		foreach ($mountIds as $mountId) {
413
-			$result[$mountId] = [];
414
-		}
415
-		foreach ($rows as $row) {
416
-			if (isset($row['type'])) {
417
-				$row['type'] = (int)$row['type'];
418
-			}
419
-			$result[$row['mount_id']][] = $row;
420
-		}
421
-		return $result;
422
-	}
423
-
424
-	/**
425
-	 * @param int[] $mountIds
426
-	 * @return array [$id => [['type' => $type, 'value' => $value], ...], ...]
427
-	 */
428
-	public function getApplicableForMounts($mountIds) {
429
-		return $this->selectForMounts('external_applicable', ['type', 'value'], $mountIds);
430
-	}
431
-
432
-	/**
433
-	 * @param int[] $mountIds
434
-	 * @return array [$id => ['key1' => $value1, ...], ...]
435
-	 */
436
-	public function getConfigForMounts($mountIds) {
437
-		$mountConfigs = $this->selectForMounts('external_config', ['key', 'value'], $mountIds);
438
-		return array_map([$this, 'createKeyValueMap'], $mountConfigs);
439
-	}
440
-
441
-	/**
442
-	 * @param int[] $mountIds
443
-	 * @return array [$id => ['key1' => $value1, ...], ...]
444
-	 */
445
-	public function getOptionsForMounts($mountIds) {
446
-		$mountOptions = $this->selectForMounts('external_options', ['key', 'value'], $mountIds);
447
-		$optionsMap = array_map([$this, 'createKeyValueMap'], $mountOptions);
448
-		return array_map(function (array $options) {
449
-			return array_map(function ($option) {
450
-				return json_decode($option);
451
-			}, $options);
452
-		}, $optionsMap);
453
-	}
454
-
455
-	/**
456
-	 * @param array $keyValuePairs [['key'=>$key, 'value=>$value], ...]
457
-	 * @return array ['key1' => $value1, ...]
458
-	 */
459
-	private function createKeyValueMap(array $keyValuePairs) {
460
-		$decryptedPairts = array_map(function ($pair) {
461
-			if ($pair['key'] === 'password') {
462
-				$pair['value'] = $this->decryptValue($pair['value']);
463
-			}
464
-			return $pair;
465
-		}, $keyValuePairs);
466
-		$keys = array_map(function ($pair) {
467
-			return $pair['key'];
468
-		}, $decryptedPairts);
469
-		$values = array_map(function ($pair) {
470
-			return $pair['value'];
471
-		}, $decryptedPairts);
472
-
473
-		return array_combine($keys, $values);
474
-	}
475
-
476
-	private function encryptValue($value) {
477
-		return $this->crypto->encrypt($value);
478
-	}
479
-
480
-	private function decryptValue($value) {
481
-		try {
482
-			return $this->crypto->decrypt($value);
483
-		} catch (\Exception $e) {
484
-			return $value;
485
-		}
486
-	}
35
+    const MOUNT_TYPE_ADMIN = 1;
36
+    const MOUNT_TYPE_PERSONAl = 2;
37
+
38
+    const APPLICABLE_TYPE_GLOBAL = 1;
39
+    const APPLICABLE_TYPE_GROUP = 2;
40
+    const APPLICABLE_TYPE_USER = 3;
41
+
42
+    /**
43
+     * @var IDBConnection
44
+     */
45
+    private $connection;
46
+
47
+    /**
48
+     * @var ICrypto
49
+     */
50
+    private $crypto;
51
+
52
+    /**
53
+     * DBConfigService constructor.
54
+     *
55
+     * @param IDBConnection $connection
56
+     * @param ICrypto $crypto
57
+     */
58
+    public function __construct(IDBConnection $connection, ICrypto $crypto) {
59
+        $this->connection = $connection;
60
+        $this->crypto = $crypto;
61
+    }
62
+
63
+    /**
64
+     * @param int $mountId
65
+     * @return array
66
+     */
67
+    public function getMountById($mountId) {
68
+        $builder = $this->connection->getQueryBuilder();
69
+        $query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
70
+            ->from('external_mounts', 'm')
71
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
72
+        $mounts = $this->getMountsFromQuery($query);
73
+        if (count($mounts) > 0) {
74
+            return $mounts[0];
75
+        } else {
76
+            return null;
77
+        }
78
+    }
79
+
80
+    /**
81
+     * Get all configured mounts
82
+     *
83
+     * @return array
84
+     */
85
+    public function getAllMounts() {
86
+        $builder = $this->connection->getQueryBuilder();
87
+        $query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
88
+            ->from('external_mounts');
89
+        return $this->getMountsFromQuery($query);
90
+    }
91
+
92
+    public function getMountsForUser($userId, $groupIds) {
93
+        $builder = $this->connection->getQueryBuilder();
94
+        $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
95
+            ->from('external_mounts', 'm')
96
+            ->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
97
+            ->where($builder->expr()->orX(
98
+                $builder->expr()->andX( // global mounts
99
+                    $builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GLOBAL, IQueryBuilder::PARAM_INT)),
100
+                    $builder->expr()->isNull('a.value')
101
+                ),
102
+                $builder->expr()->andX( // mounts for user
103
+                    $builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_USER, IQueryBuilder::PARAM_INT)),
104
+                    $builder->expr()->eq('a.value', $builder->createNamedParameter($userId))
105
+                ),
106
+                $builder->expr()->andX( // mounts for group
107
+                    $builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GROUP, IQueryBuilder::PARAM_INT)),
108
+                    $builder->expr()->in('a.value', $builder->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY))
109
+                )
110
+            ));
111
+
112
+        return $this->getMountsFromQuery($query);
113
+    }
114
+
115
+    /**
116
+     * Get admin defined mounts
117
+     *
118
+     * @return array
119
+     */
120
+    public function getAdminMounts() {
121
+        $builder = $this->connection->getQueryBuilder();
122
+        $query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
123
+            ->from('external_mounts')
124
+            ->where($builder->expr()->eq('type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT)));
125
+        return $this->getMountsFromQuery($query);
126
+    }
127
+
128
+    protected function getForQuery(IQueryBuilder $builder, $type, $value) {
129
+        $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
130
+            ->from('external_mounts', 'm')
131
+            ->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
132
+            ->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)));
133
+
134
+        if (is_null($value)) {
135
+            $query = $query->andWhere($builder->expr()->isNull('a.value'));
136
+        } else {
137
+            $query = $query->andWhere($builder->expr()->eq('a.value', $builder->createNamedParameter($value)));
138
+        }
139
+
140
+        return $query;
141
+    }
142
+
143
+    /**
144
+     * Get mounts by applicable
145
+     *
146
+     * @param int $type any of the self::APPLICABLE_TYPE_ constants
147
+     * @param string|null $value user_id, group_id or null for global mounts
148
+     * @return array
149
+     */
150
+    public function getMountsFor($type, $value) {
151
+        $builder = $this->connection->getQueryBuilder();
152
+        $query = $this->getForQuery($builder, $type, $value);
153
+
154
+        return $this->getMountsFromQuery($query);
155
+    }
156
+
157
+    /**
158
+     * Get admin defined mounts by applicable
159
+     *
160
+     * @param int $type any of the self::APPLICABLE_TYPE_ constants
161
+     * @param string|null $value user_id, group_id or null for global mounts
162
+     * @return array
163
+     */
164
+    public function getAdminMountsFor($type, $value) {
165
+        $builder = $this->connection->getQueryBuilder();
166
+        $query = $this->getForQuery($builder, $type, $value);
167
+        $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT)));
168
+
169
+        return $this->getMountsFromQuery($query);
170
+    }
171
+
172
+    /**
173
+     * Get admin defined mounts for multiple applicable
174
+     *
175
+     * @param int $type any of the self::APPLICABLE_TYPE_ constants
176
+     * @param string[] $values user_ids or group_ids
177
+     * @return array
178
+     */
179
+    public function getAdminMountsForMultiple($type, array $values) {
180
+        $builder = $this->connection->getQueryBuilder();
181
+        $params = array_map(function ($value) use ($builder) {
182
+            return $builder->createNamedParameter($value, IQueryBuilder::PARAM_STR);
183
+        }, $values);
184
+
185
+        $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
186
+            ->from('external_mounts', 'm')
187
+            ->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
188
+            ->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)))
189
+            ->andWhere($builder->expr()->in('a.value', $params));
190
+        $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT)));
191
+
192
+        return $this->getMountsFromQuery($query);
193
+    }
194
+
195
+    /**
196
+     * Get user defined mounts by applicable
197
+     *
198
+     * @param int $type any of the self::APPLICABLE_TYPE_ constants
199
+     * @param string|null $value user_id, group_id or null for global mounts
200
+     * @return array
201
+     */
202
+    public function getUserMountsFor($type, $value) {
203
+        $builder = $this->connection->getQueryBuilder();
204
+        $query = $this->getForQuery($builder, $type, $value);
205
+        $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_PERSONAl, IQueryBuilder::PARAM_INT)));
206
+
207
+        return $this->getMountsFromQuery($query);
208
+    }
209
+
210
+    /**
211
+     * Add a mount to the database
212
+     *
213
+     * @param string $mountPoint
214
+     * @param string $storageBackend
215
+     * @param string $authBackend
216
+     * @param int $priority
217
+     * @param int $type self::MOUNT_TYPE_ADMIN or self::MOUNT_TYPE_PERSONAL
218
+     * @return int the id of the new mount
219
+     */
220
+    public function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
221
+        if (!$priority) {
222
+            $priority = 100;
223
+        }
224
+        $builder = $this->connection->getQueryBuilder();
225
+        $query = $builder->insert('external_mounts')
226
+            ->values([
227
+                'mount_point' => $builder->createNamedParameter($mountPoint, IQueryBuilder::PARAM_STR),
228
+                'storage_backend' => $builder->createNamedParameter($storageBackend, IQueryBuilder::PARAM_STR),
229
+                'auth_backend' => $builder->createNamedParameter($authBackend, IQueryBuilder::PARAM_STR),
230
+                'priority' => $builder->createNamedParameter($priority, IQueryBuilder::PARAM_INT),
231
+                'type' => $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)
232
+            ]);
233
+        $query->execute();
234
+        return (int)$this->connection->lastInsertId('*PREFIX*external_mounts');
235
+    }
236
+
237
+    /**
238
+     * Remove a mount from the database
239
+     *
240
+     * @param int $mountId
241
+     */
242
+    public function removeMount($mountId) {
243
+        $builder = $this->connection->getQueryBuilder();
244
+        $query = $builder->delete('external_mounts')
245
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
246
+        $query->execute();
247
+
248
+        $query = $builder->delete('external_applicable')
249
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
250
+        $query->execute();
251
+
252
+        $query = $builder->delete('external_config')
253
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
254
+        $query->execute();
255
+
256
+        $query = $builder->delete('external_options')
257
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
258
+        $query->execute();
259
+    }
260
+
261
+    /**
262
+     * @param int $mountId
263
+     * @param string $newMountPoint
264
+     */
265
+    public function setMountPoint($mountId, $newMountPoint) {
266
+        $builder = $this->connection->getQueryBuilder();
267
+
268
+        $query = $builder->update('external_mounts')
269
+            ->set('mount_point', $builder->createNamedParameter($newMountPoint))
270
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
271
+
272
+        $query->execute();
273
+    }
274
+
275
+    /**
276
+     * @param int $mountId
277
+     * @param string $newAuthBackend
278
+     */
279
+    public function setAuthBackend($mountId, $newAuthBackend) {
280
+        $builder = $this->connection->getQueryBuilder();
281
+
282
+        $query = $builder->update('external_mounts')
283
+            ->set('auth_backend', $builder->createNamedParameter($newAuthBackend))
284
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
285
+
286
+        $query->execute();
287
+    }
288
+
289
+    /**
290
+     * @param int $mountId
291
+     * @param string $key
292
+     * @param string $value
293
+     */
294
+    public function setConfig($mountId, $key, $value) {
295
+        if ($key === 'password') {
296
+            $value = $this->encryptValue($value);
297
+        }
298
+        $count = $this->connection->insertIfNotExist('*PREFIX*external_config', [
299
+            'mount_id' => $mountId,
300
+            'key' => $key,
301
+            'value' => $value
302
+        ], ['mount_id', 'key']);
303
+        if ($count === 0) {
304
+            $builder = $this->connection->getQueryBuilder();
305
+            $query = $builder->update('external_config')
306
+                ->set('value', $builder->createNamedParameter($value, IQueryBuilder::PARAM_STR))
307
+                ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
308
+                ->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, IQueryBuilder::PARAM_STR)));
309
+            $query->execute();
310
+        }
311
+    }
312
+
313
+    /**
314
+     * @param int $mountId
315
+     * @param string $key
316
+     * @param string $value
317
+     */
318
+    public function setOption($mountId, $key, $value) {
319
+
320
+        $count = $this->connection->insertIfNotExist('*PREFIX*external_options', [
321
+            'mount_id' => $mountId,
322
+            'key' => $key,
323
+            'value' => json_encode($value)
324
+        ], ['mount_id', 'key']);
325
+        if ($count === 0) {
326
+            $builder = $this->connection->getQueryBuilder();
327
+            $query = $builder->update('external_options')
328
+                ->set('value', $builder->createNamedParameter(json_encode($value), IQueryBuilder::PARAM_STR))
329
+                ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
330
+                ->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, IQueryBuilder::PARAM_STR)));
331
+            $query->execute();
332
+        }
333
+    }
334
+
335
+    public function addApplicable($mountId, $type, $value) {
336
+        $this->connection->insertIfNotExist('*PREFIX*external_applicable', [
337
+            'mount_id' => $mountId,
338
+            'type' => $type,
339
+            'value' => $value
340
+        ], ['mount_id', 'type', 'value']);
341
+    }
342
+
343
+    public function removeApplicable($mountId, $type, $value) {
344
+        $builder = $this->connection->getQueryBuilder();
345
+        $query = $builder->delete('external_applicable')
346
+            ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
347
+            ->andWhere($builder->expr()->eq('type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT)));
348
+
349
+        if (is_null($value)) {
350
+            $query = $query->andWhere($builder->expr()->isNull('value'));
351
+        } else {
352
+            $query = $query->andWhere($builder->expr()->eq('value', $builder->createNamedParameter($value, IQueryBuilder::PARAM_STR)));
353
+        }
354
+
355
+        $query->execute();
356
+    }
357
+
358
+    private function getMountsFromQuery(IQueryBuilder $query) {
359
+        $result = $query->execute();
360
+        $mounts = $result->fetchAll();
361
+        $uniqueMounts = [];
362
+        foreach ($mounts as $mount) {
363
+            $id = $mount['mount_id'];
364
+            if (!isset($uniqueMounts[$id])) {
365
+                $uniqueMounts[$id] = $mount;
366
+            }
367
+        }
368
+        $uniqueMounts = array_values($uniqueMounts);
369
+
370
+        $mountIds = array_map(function ($mount) {
371
+            return $mount['mount_id'];
372
+        }, $uniqueMounts);
373
+        $mountIds = array_values(array_unique($mountIds));
374
+
375
+        $applicable = $this->getApplicableForMounts($mountIds);
376
+        $config = $this->getConfigForMounts($mountIds);
377
+        $options = $this->getOptionsForMounts($mountIds);
378
+
379
+        return array_map(function ($mount, $applicable, $config, $options) {
380
+            $mount['type'] = (int)$mount['type'];
381
+            $mount['priority'] = (int)$mount['priority'];
382
+            $mount['applicable'] = $applicable;
383
+            $mount['config'] = $config;
384
+            $mount['options'] = $options;
385
+            return $mount;
386
+        }, $uniqueMounts, $applicable, $config, $options);
387
+    }
388
+
389
+    /**
390
+     * Get mount options from a table grouped by mount id
391
+     *
392
+     * @param string $table
393
+     * @param string[] $fields
394
+     * @param int[] $mountIds
395
+     * @return array [$mountId => [['field1' => $value1, ...], ...], ...]
396
+     */
397
+    private function selectForMounts($table, array $fields, array $mountIds) {
398
+        if (count($mountIds) === 0) {
399
+            return [];
400
+        }
401
+        $builder = $this->connection->getQueryBuilder();
402
+        $fields[] = 'mount_id';
403
+        $placeHolders = array_map(function ($id) use ($builder) {
404
+            return $builder->createPositionalParameter($id, IQueryBuilder::PARAM_INT);
405
+        }, $mountIds);
406
+        $query = $builder->select($fields)
407
+            ->from($table)
408
+            ->where($builder->expr()->in('mount_id', $placeHolders));
409
+        $rows = $query->execute()->fetchAll();
410
+
411
+        $result = [];
412
+        foreach ($mountIds as $mountId) {
413
+            $result[$mountId] = [];
414
+        }
415
+        foreach ($rows as $row) {
416
+            if (isset($row['type'])) {
417
+                $row['type'] = (int)$row['type'];
418
+            }
419
+            $result[$row['mount_id']][] = $row;
420
+        }
421
+        return $result;
422
+    }
423
+
424
+    /**
425
+     * @param int[] $mountIds
426
+     * @return array [$id => [['type' => $type, 'value' => $value], ...], ...]
427
+     */
428
+    public function getApplicableForMounts($mountIds) {
429
+        return $this->selectForMounts('external_applicable', ['type', 'value'], $mountIds);
430
+    }
431
+
432
+    /**
433
+     * @param int[] $mountIds
434
+     * @return array [$id => ['key1' => $value1, ...], ...]
435
+     */
436
+    public function getConfigForMounts($mountIds) {
437
+        $mountConfigs = $this->selectForMounts('external_config', ['key', 'value'], $mountIds);
438
+        return array_map([$this, 'createKeyValueMap'], $mountConfigs);
439
+    }
440
+
441
+    /**
442
+     * @param int[] $mountIds
443
+     * @return array [$id => ['key1' => $value1, ...], ...]
444
+     */
445
+    public function getOptionsForMounts($mountIds) {
446
+        $mountOptions = $this->selectForMounts('external_options', ['key', 'value'], $mountIds);
447
+        $optionsMap = array_map([$this, 'createKeyValueMap'], $mountOptions);
448
+        return array_map(function (array $options) {
449
+            return array_map(function ($option) {
450
+                return json_decode($option);
451
+            }, $options);
452
+        }, $optionsMap);
453
+    }
454
+
455
+    /**
456
+     * @param array $keyValuePairs [['key'=>$key, 'value=>$value], ...]
457
+     * @return array ['key1' => $value1, ...]
458
+     */
459
+    private function createKeyValueMap(array $keyValuePairs) {
460
+        $decryptedPairts = array_map(function ($pair) {
461
+            if ($pair['key'] === 'password') {
462
+                $pair['value'] = $this->decryptValue($pair['value']);
463
+            }
464
+            return $pair;
465
+        }, $keyValuePairs);
466
+        $keys = array_map(function ($pair) {
467
+            return $pair['key'];
468
+        }, $decryptedPairts);
469
+        $values = array_map(function ($pair) {
470
+            return $pair['value'];
471
+        }, $decryptedPairts);
472
+
473
+        return array_combine($keys, $values);
474
+    }
475
+
476
+    private function encryptValue($value) {
477
+        return $this->crypto->encrypt($value);
478
+    }
479
+
480
+    private function decryptValue($value) {
481
+        try {
482
+            return $this->crypto->decrypt($value);
483
+        } catch (\Exception $e) {
484
+            return $value;
485
+        }
486
+    }
487 487
 }
Please login to merge, or discard this patch.