Passed
Push — master ( 7fa061...fde4c5 )
by Morris
12:18
created

Manager::stripPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Bjoern Schiessle <[email protected]>
6
 * @author Björn Schießle <[email protected]>
7
 * @author Daniel Hansson <[email protected]>
8
 * @author Joas Schilling <[email protected]>
9
 * @author Jörn Friedrich Dreyer <[email protected]>
10
 * @author Lukas Reschke <[email protected]>
11
 * @author Morris Jobke <[email protected]>
12
 * @author Robin Appelman <[email protected]>
13
 * @author Roeland Jago Douma <[email protected]>
14
 * @author Stefan Weil <[email protected]>
15
 *
16
 * @license AGPL-3.0
17
 *
18
 * This code is free software: you can redistribute it and/or modify
19
 * it under the terms of the GNU Affero General Public License, version 3,
20
 * as published by the Free Software Foundation.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
 * GNU Affero General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU Affero General Public License, version 3,
28
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
29
 *
30
 */
31
32
namespace OCA\Files_Sharing\External;
33
34
use OC\Files\Filesystem;
35
use OCA\Files_Sharing\Helper;
36
use OCP\Federation\ICloudFederationFactory;
37
use OCP\Federation\ICloudFederationProviderManager;
38
use OCP\Files;
39
use OCP\Files\Storage\IStorageFactory;
40
use OCP\Http\Client\IClientService;
41
use OCP\IDBConnection;
42
use OCP\IGroupManager;
43
use OCP\IUserManager;
44
use OCP\Notification\IManager;
45
use OCP\OCS\IDiscoveryService;
46
use OCP\Share;
47
48
class Manager {
49
	const STORAGE = '\OCA\Files_Sharing\External\Storage';
50
51
	/**
52
	 * @var string
53
	 */
54
	private $uid;
55
56
	/**
57
	 * @var IDBConnection
58
	 */
59
	private $connection;
60
61
	/**
62
	 * @var \OC\Files\Mount\Manager
63
	 */
64
	private $mountManager;
65
66
	/**
67
	 * @var IStorageFactory
68
	 */
69
	private $storageLoader;
70
71
	/**
72
	 * @var IClientService
73
	 */
74
	private $clientService;
75
76
	/**
77
	 * @var IManager
78
	 */
79
	private $notificationManager;
80
81
	/**
82
	 * @var IDiscoveryService
83
	 */
84
	private $discoveryService;
85
86
	/** @var ICloudFederationProviderManager */
87
	private $cloudFederationProviderManager;
88
89
	/** @var ICloudFederationFactory */
90
	private $cloudFederationFactory;
91
92
	/** @var IGroupManager  */
93
	private $groupManager;
94
95
	/** @var IUserManager */
96
	private $userManager;
97
98
	/**
99
	 * @param IDBConnection $connection
100
	 * @param \OC\Files\Mount\Manager $mountManager
101
	 * @param IStorageFactory $storageLoader
102
	 * @param IClientService $clientService
103
	 * @param IManager $notificationManager
104
	 * @param IDiscoveryService $discoveryService
105
	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
106
	 * @param ICloudFederationFactory $cloudFederationFactory
107
	 * @param IGroupManager $groupManager
108
	 * @param IUserManager $userManager
109
	 * @param string $uid
110
	 */
111
	public function __construct(IDBConnection $connection,
112
								\OC\Files\Mount\Manager $mountManager,
113
								IStorageFactory $storageLoader,
114
								IClientService $clientService,
115
								IManager $notificationManager,
116
								IDiscoveryService $discoveryService,
117
								ICloudFederationProviderManager $cloudFederationProviderManager,
118
								ICloudFederationFactory $cloudFederationFactory,
119
								IGroupManager $groupManager,
120
								IUserManager $userManager,
121
								$uid) {
122
		$this->connection = $connection;
123
		$this->mountManager = $mountManager;
124
		$this->storageLoader = $storageLoader;
125
		$this->clientService = $clientService;
126
		$this->uid = $uid;
127
		$this->notificationManager = $notificationManager;
128
		$this->discoveryService = $discoveryService;
129
		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
130
		$this->cloudFederationFactory = $cloudFederationFactory;
131
		$this->groupManager = $groupManager;
132
		$this->userManager = $userManager;
133
	}
134
135
	/**
136
	 * add new server-to-server share
137
	 *
138
	 * @param string $remote
139
	 * @param string $token
140
	 * @param string $password
141
	 * @param string $name
142
	 * @param string $owner
143
	 * @param int $shareType
144
	 * @param boolean $accepted
145
	 * @param string $user
146
	 * @param int $remoteId
147
	 * @param int $parent
148
	 * @return Mount|null
149
	 * @throws \Doctrine\DBAL\DBALException
150
	 */
151
	public function addShare($remote, $token, $password, $name, $owner, $shareType, $accepted=false, $user = null, $remoteId = -1, $parent = -1) {
152
153
		$user = $user ? $user : $this->uid;
154
		$accepted = $accepted ? 1 : 0;
155
		$name = Filesystem::normalizePath('/' . $name);
156
157
		if (!$accepted) {
158
			// To avoid conflicts with the mount point generation later,
159
			// we only use a temporary mount point name here. The real
160
			// mount point name will be generated when accepting the share,
161
			// using the original share item name.
162
			$tmpMountPointName = '{{TemporaryMountPointName#' . $name . '}}';
163
			$mountPoint = $tmpMountPointName;
164
			$hash = md5($tmpMountPointName);
165
			$data = [
166
				'remote'		=> $remote,
167
				'share_token'	=> $token,
168
				'password'		=> $password,
169
				'name'			=> $name,
170
				'owner'			=> $owner,
171
				'user'			=> $user,
172
				'mountpoint'	=> $mountPoint,
173
				'mountpoint_hash'	=> $hash,
174
				'accepted'		=> $accepted,
175
				'remote_id'		=> $remoteId,
176
				'share_type'    => $shareType,
177
			];
178
179
			$i = 1;
180
			while (!$this->connection->insertIfNotExist('*PREFIX*share_external', $data, ['user', 'mountpoint_hash'])) {
0 ignored issues
show
Deprecated Code introduced by
The function OCP\IDBConnection::insertIfNotExist() has been deprecated: 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

180
			while (!/** @scrutinizer ignore-deprecated */ $this->connection->insertIfNotExist('*PREFIX*share_external', $data, ['user', 'mountpoint_hash'])) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
181
				// The external share already exists for the user
182
				$data['mountpoint'] = $tmpMountPointName . '-' . $i;
183
				$data['mountpoint_hash'] = md5($data['mountpoint']);
184
				$i++;
185
			}
186
			return null;
187
		}
188
189
		$mountPoint = Files::buildNotExistingFileName('/', $name);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Files::buildNotExistingFileName() has been deprecated: 14.0.0 use getNonExistingName of the OCP\Files\Folder object ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

189
		$mountPoint = /** @scrutinizer ignore-deprecated */ Files::buildNotExistingFileName('/', $name);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
190
		$mountPoint = Filesystem::normalizePath('/' . $mountPoint);
191
		$hash = md5($mountPoint);
192
193
		$this->writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType);
194
195
		$options = array(
196
			'remote'	=> $remote,
197
			'token'		=> $token,
198
			'password'	=> $password,
199
			'mountpoint'	=> $mountPoint,
200
			'owner'		=> $owner
201
		);
202
		return $this->mountShare($options);
203
	}
204
205
	/**
206
	 * write remote share to the database
207
	 *
208
	 * @param $remote
209
	 * @param $token
210
	 * @param $password
211
	 * @param $name
212
	 * @param $owner
213
	 * @param $user
214
	 * @param $mountPoint
215
	 * @param $hash
216
	 * @param $accepted
217
	 * @param $remoteId
218
	 * @param $parent
219
	 * @param $shareType
220
	 * @return bool
221
	 */
222
	private function writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType) {
223
		$query = $this->connection->prepare('
224
				INSERT INTO `*PREFIX*share_external`
225
					(`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`, `parent`, `share_type`)
226
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
227
			');
228
		return $query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType));
229
	}
230
231
	/**
232
	 * get share
233
	 *
234
	 * @param int $id share id
235
	 * @return mixed share of false
236
	 */
237
	public function getShare($id) {
238
		$getShare = $this->connection->prepare('
239
			SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`, `parent`, `share_type`, `password`, `mountpoint_hash`
240
			FROM  `*PREFIX*share_external`
241
			WHERE `id` = ?');
242
		$result = $getShare->execute(array($id));
243
244
		$share = $result ? $getShare->fetch() : [];
245
246
		$validShare = is_array($share) && isset($share['share_type']) && isset($share['user']);
247
248
		// check if the user is allowed to access it
249
		if ($validShare && (int)$share['share_type'] === Share::SHARE_TYPE_USER && $share['user'] === $this->uid) {
250
			return $share;
251
		} else if ($validShare && (int)$share['share_type'] === Share::SHARE_TYPE_GROUP) {
252
			$user = $this->userManager->get($this->uid);
253
			if ($this->groupManager->get($share['user'])->inGroup($user)) {
254
				return $share;
255
			}
256
		}
257
258
		return false;
259
260
	}
261
262
	/**
263
	 * accept server-to-server share
264
	 *
265
	 * @param int $id
266
	 * @return bool True if the share could be accepted, false otherwise
267
	 */
268
	public function acceptShare($id) {
269
270
		$share = $this->getShare($id);
271
		$result = false;
272
273
		if ($share) {
274
			\OC_Util::setupFS($this->uid);
275
			$shareFolder = Helper::getShareFolder();
276
			$mountPoint = Files::buildNotExistingFileName($shareFolder, $share['name']);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Files::buildNotExistingFileName() has been deprecated: 14.0.0 use getNonExistingName of the OCP\Files\Folder object ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

276
			$mountPoint = /** @scrutinizer ignore-deprecated */ Files::buildNotExistingFileName($shareFolder, $share['name']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
277
			$mountPoint = Filesystem::normalizePath($mountPoint);
278
			$hash = md5($mountPoint);
279
			$userShareAccepted = false;
280
281
			if((int)$share['share_type'] === Share::SHARE_TYPE_USER) {
282
				$acceptShare = $this->connection->prepare('
283
				UPDATE `*PREFIX*share_external`
284
				SET `accepted` = ?,
285
					`mountpoint` = ?,
286
					`mountpoint_hash` = ?
287
				WHERE `id` = ? AND `user` = ?');
288
				$userShareAccepted = $acceptShare->execute(array(1, $mountPoint, $hash, $id, $this->uid));
289
			} else {
290
				$result = $this->writeShareToDb(
291
					$share['remote'],
292
					$share['share_token'],
293
					$share['password'],
294
					$share['name'],
295
					$share['owner'],
296
					$this->uid,
297
					$mountPoint, $hash, 1,
298
					$share['remote_id'],
299
					$id,
300
					$share['share_type']);
301
			}
302
			if ($userShareAccepted === true) {
303
				$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'accept');
304
				\OC_Hook::emit(Share::class, 'federated_share_added', ['server' => $share['remote']]);
305
				$result = true;
306
			}
307
		}
308
309
		// Make sure the user has no notification for something that does not exist anymore.
310
		$this->processNotification($id);
311
312
		return $result;
313
	}
314
315
	/**
316
	 * decline server-to-server share
317
	 *
318
	 * @param int $id
319
	 * @return bool True if the share could be declined, false otherwise
320
	 */
321
	public function declineShare($id) {
322
323
		$share = $this->getShare($id);
324
		$result = false;
325
326
		if ($share && (int)$share['share_type'] === Share::SHARE_TYPE_USER) {
327
			$removeShare = $this->connection->prepare('
328
				DELETE FROM `*PREFIX*share_external` WHERE `id` = ? AND `user` = ?');
329
			$removeShare->execute(array($id, $this->uid));
330
			$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
331
332
			$this->processNotification($id);
333
			$result = true;
334
		} else if ($share && (int)$share['share_type'] === Share::SHARE_TYPE_GROUP) {
335
			$result = $this->writeShareToDb(
336
				$share['remote'],
337
				$share['share_token'],
338
				$share['password'],
339
				$share['name'],
340
				$share['owner'],
341
				$this->uid,
342
				$share['mountpoint'],
343
				$share['mountpoint_hash'],
344
				0,
345
				$share['remote_id'],
346
				$id,
347
				$share['share_type']);
348
			$this->processNotification($id);
349
		}
350
351
		return $result;
352
	}
353
354
	/**
355
	 * @param int $remoteShare
356
	 */
357
	public function processNotification($remoteShare) {
358
		$filter = $this->notificationManager->createNotification();
359
		$filter->setApp('files_sharing')
360
			->setUser($this->uid)
361
			->setObject('remote_share', (int) $remoteShare);
362
		$this->notificationManager->markProcessed($filter);
363
	}
364
365
	/**
366
	 * inform remote server whether server-to-server share was accepted/declined
367
	 *
368
	 * @param string $remote
369
	 * @param string $token
370
	 * @param int $remoteId Share id on the remote host
371
	 * @param string $feedback
372
	 * @return boolean
373
	 */
374
	private function sendFeedbackToRemote($remote, $token, $remoteId, $feedback) {
375
376
		$result = $this->tryOCMEndPoint($remote, $token, $remoteId, $feedback);
377
378
		if($result === true) {
379
			return true;
380
		}
381
382
		$federationEndpoints = $this->discoveryService->discover($remote, 'FEDERATED_SHARING');
383
		$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
384
385
		$url = rtrim($remote, '/') . $endpoint . '/' . $remoteId . '/' . $feedback . '?format=' . Share::RESPONSE_FORMAT;
386
		$fields = array('token' => $token);
387
388
		$client = $this->clientService->newClient();
389
390
		try {
391
			$response = $client->post(
392
				$url,
393
				[
394
					'body' => $fields,
395
					'connect_timeout' => 10,
396
				]
397
			);
398
		} catch (\Exception $e) {
399
			return false;
400
		}
401
402
		$status = json_decode($response->getBody(), true);
403
404
		return ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
405
	}
406
407
	/**
408
	 * try send accept message to ocm end-point
409
	 *
410
	 * @param string $remoteDomain
411
	 * @param string $token
412
	 * @param $remoteId id of the share
0 ignored issues
show
Bug introduced by
The type OCA\Files_Sharing\External\id was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
413
	 * @param string $feedback
414
	 * @return bool
415
	 */
416
	protected function tryOCMEndPoint($remoteDomain, $token, $remoteId, $feedback) {
417
		switch ($feedback) {
418
			case 'accept':
419
				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
420
				$notification->setMessage(
421
					'SHARE_ACCEPTED',
422
					'file',
423
					$remoteId,
424
					[
425
						'sharedSecret' => $token,
426
						'message' => 'Recipient accept the share'
427
					]
428
429
				);
430
				return $this->cloudFederationProviderManager->sendNotification($remoteDomain, $notification);
431
			case 'decline':
432
				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
433
				$notification->setMessage(
434
					'SHARE_DECLINED',
435
					'file',
436
					$remoteId,
437
					[
438
						'sharedSecret' => $token,
439
						'message' => 'Recipient declined the share'
440
					]
441
442
				);
443
				return $this->cloudFederationProviderManager->sendNotification($remoteDomain, $notification);
444
		}
445
446
		return false;
447
448
	}
449
450
451
	/**
452
	 * remove '/user/files' from the path and trailing slashes
453
	 *
454
	 * @param string $path
455
	 * @return string
456
	 */
457
	protected function stripPath($path) {
458
		$prefix = '/' . $this->uid . '/files';
459
		return rtrim(substr($path, strlen($prefix)), '/');
460
	}
461
462
	public function getMount($data) {
463
		$data['manager'] = $this;
464
		$mountPoint = '/' . $this->uid . '/files' . $data['mountpoint'];
465
		$data['mountpoint'] = $mountPoint;
466
		$data['certificateManager'] = \OC::$server->getCertificateManager($this->uid);
467
		return new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader);
468
	}
469
470
	/**
471
	 * @param array $data
472
	 * @return Mount
473
	 */
474
	protected function mountShare($data) {
475
		$mount = $this->getMount($data);
476
		$this->mountManager->addMount($mount);
477
		return $mount;
478
	}
479
480
	/**
481
	 * @return \OC\Files\Mount\Manager
482
	 */
483
	public function getMountManager() {
484
		return $this->mountManager;
485
	}
486
487
	/**
488
	 * @param string $source
489
	 * @param string $target
490
	 * @return bool
491
	 */
492
	public function setMountPoint($source, $target) {
493
		$source = $this->stripPath($source);
494
		$target = $this->stripPath($target);
495
		$sourceHash = md5($source);
496
		$targetHash = md5($target);
497
498
		$query = $this->connection->prepare('
499
			UPDATE `*PREFIX*share_external`
500
			SET `mountpoint` = ?, `mountpoint_hash` = ?
501
			WHERE `mountpoint_hash` = ?
502
			AND `user` = ?
503
		');
504
		$result = (bool)$query->execute(array($target, $targetHash, $sourceHash, $this->uid));
505
506
		return $result;
507
	}
508
509
	public function removeShare($mountPoint) {
510
511
		$mountPointObj = $this->mountManager->find($mountPoint);
512
		$id = $mountPointObj->getStorage()->getCache()->getId('');
513
514
		$mountPoint = $this->stripPath($mountPoint);
515
		$hash = md5($mountPoint);
516
517
		$getShare = $this->connection->prepare('
518
			SELECT `remote`, `share_token`, `remote_id`, `share_type`, `id`
519
			FROM  `*PREFIX*share_external`
520
			WHERE `mountpoint_hash` = ? AND `user` = ?');
521
		$result = $getShare->execute(array($hash, $this->uid));
522
523
		$share = $getShare->fetch();
524
		$getShare->closeCursor();
525
		if ($result && (bool)$share !== false && (int)$share['share_type'] === Share::SHARE_TYPE_USER) {
526
			try {
527
				$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
528
			} catch (\Exception $e) {
529
				// if we fail to notify the remote (probably cause the remote is down)
530
				// we still want the share to be gone to prevent undeletable remotes
531
			}
532
533
			$query = $this->connection->prepare('
534
			DELETE FROM `*PREFIX*share_external`
535
			WHERE `id` = ?
536
			');
537
			$result = (bool)$query->execute(array((int)$share['id']));
538
		} else if ($result && (int)$share['share_type'] === Share::SHARE_TYPE_GROUP) {
539
			$query = $this->connection->prepare('
540
				UPDATE `*PREFIX*share_external`
541
				SET `accepted` = ?
542
				WHERE `id` = ?');
543
			$result = (bool)$query->execute(array(0, (int)$share['id']));
544
		}
545
546
		if($result) {
547
			$this->removeReShares($id);
548
		}
549
550
		return $result;
551
	}
552
553
	/**
554
	 * remove re-shares from share table and mapping in the federated_reshares table
555
	 *
556
	 * @param $mountPointId
557
	 */
558
	protected function removeReShares($mountPointId) {
559
		$selectQuery = $this->connection->getQueryBuilder();
560
		$query = $this->connection->getQueryBuilder();
561
		$selectQuery->select('id')->from('share')
562
			->where($selectQuery->expr()->eq('file_source', $query->createNamedParameter($mountPointId)));
563
		$select = $selectQuery->getSQL();
564
565
566
		$query->delete('federated_reshares')
567
			->where($query->expr()->in('share_id', $query->createFunction('(' . $select . ')')));
568
		$query->execute();
569
570
		$deleteReShares = $this->connection->getQueryBuilder();
571
		$deleteReShares->delete('share')
572
			->where($deleteReShares->expr()->eq('file_source', $deleteReShares->createNamedParameter($mountPointId)));
573
		$deleteReShares->execute();
574
	}
575
576
	/**
577
	 * remove all shares for user $uid if the user was deleted
578
	 *
579
	 * @param string $uid
580
	 * @return bool
581
	 */
582
	public function removeUserShares($uid) {
583
		$getShare = $this->connection->prepare('
584
			SELECT `remote`, `share_token`, `remote_id`
585
			FROM  `*PREFIX*share_external`
586
			WHERE `user` = ?');
587
		$result = $getShare->execute(array($uid));
588
589
		if ($result) {
590
			$shares = $getShare->fetchAll();
591
			foreach($shares as $share) {
592
				$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
593
			}
594
		}
595
596
		$query = $this->connection->prepare('
597
			DELETE FROM `*PREFIX*share_external`
598
			WHERE `user` = ?
599
		');
600
		return (bool)$query->execute(array($uid));
601
	}
602
603
	/**
604
	 * return a list of shares which are not yet accepted by the user
605
	 *
606
	 * @return array list of open server-to-server shares
607
	 */
608
	public function getOpenShares() {
609
		return $this->getShares(false);
610
	}
611
612
	/**
613
	 * return a list of shares which are accepted by the user
614
	 *
615
	 * @return array list of accepted server-to-server shares
616
	 */
617
	public function getAcceptedShares() {
618
		return $this->getShares(true);
619
	}
620
621
	/**
622
	 * return a list of shares for the user
623
	 *
624
	 * @param bool|null $accepted True for accepted only,
625
	 *                            false for not accepted,
626
	 *                            null for all shares of the user
627
	 * @return array list of open server-to-server shares
628
	 */
629
	private function getShares($accepted) {
630
		$user = $this->userManager->get($this->uid);
631
		$groups = $this->groupManager->getUserGroups($user);
632
		$userGroups = [];
633
		foreach ($groups as $group) {
634
			$userGroups[] = $group->getGID();
635
		}
636
637
		$query = 'SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`
638
		          FROM `*PREFIX*share_external` 
639
				  WHERE (`user` = ? OR `user` IN (?))';
640
		$parameters = [$this->uid, implode(',',$userGroups)];
641
		if (!is_null($accepted)) {
642
			$query .= ' AND `accepted` = ?';
643
			$parameters[] = (int) $accepted;
644
		}
645
		$query .= ' ORDER BY `id` ASC';
646
647
		$shares = $this->connection->prepare($query);
648
		$result = $shares->execute($parameters);
649
650
		return $result ? $shares->fetchAll() : [];
651
	}
652
}
653