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