Completed
Pull Request — master (#32303)
by Victor
10:56
created

FedShareManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 8
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @author Viktar Dubiniuk <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OCA\FederatedFileSharing;
23
24
use OCA\FederatedFileSharing\Ocm\Permissions;
25
use OCA\Files_Sharing\Activity;
26
use OCP\Activity\IManager as ActivityManager;
27
use OCP\Files\NotFoundException;
28
use OCP\IUserManager;
29
use OCP\Notification\IManager as NotificationManager;
30
use OCP\Share\IShare;
31
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
32
use Symfony\Component\EventDispatcher\GenericEvent;
33
34
/**
35
 * Class FedShareManager holds the share logic
36
 *
37
 * @package OCA\FederatedFileSharing
38
 */
39
class FedShareManager {
40
	const ACTION_URL = 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/';
41
42
	/**
43
	 * @var FederatedShareProvider
44
	 */
45
	private $federatedShareProvider;
46
47
	/**
48
	 * @var Notifications
49
	 */
50
	private $notifications;
51
52
	/**
53
	 * @var IUserManager
54
	 */
55
	private $userManager;
56
57
	/**
58
	 * @var ActivityManager
59
	 */
60
	private $activityManager;
61
62
	/**
63
	 * @var NotificationManager
64
	 */
65
	private $notificationManager;
66
67
	/**
68
	 * @var AddressHandler
69
	 */
70
	private $addressHandler;
71
72
	/**
73
	 * @var Permissions
74
	 */
75
	private $permissions;
76
77
	/**
78
	 * @var EventDispatcherInterface
79
	 */
80
	private $eventDispatcher;
81
82
	/**
83
	 * FedShareManager constructor.
84
	 *
85
	 * @param FederatedShareProvider $federatedShareProvider
86
	 * @param Notifications $notifications
87
	 * @param IUserManager $userManager
88
	 * @param ActivityManager $activityManager
89
	 * @param NotificationManager $notificationManager
90
	 * @param AddressHandler $addressHandler
91
	 * @param Permissions $permissions
92
	 * @param EventDispatcherInterface $eventDispatcher
93
	 */
94
	public function __construct(FederatedShareProvider $federatedShareProvider,
95
								Notifications $notifications,
96
								IUserManager $userManager,
97
								ActivityManager $activityManager,
98
								NotificationManager $notificationManager,
99
								AddressHandler $addressHandler,
100
								Permissions $permissions,
101
								EventDispatcherInterface $eventDispatcher
102
	) {
103
		$this->federatedShareProvider = $federatedShareProvider;
104
		$this->notifications = $notifications;
105
		$this->userManager = $userManager;
106
		$this->activityManager = $activityManager;
107
		$this->notificationManager = $notificationManager;
108
		$this->addressHandler = $addressHandler;
109
		$this->permissions = $permissions;
110
		$this->eventDispatcher = $eventDispatcher;
111
	}
112
113
	/**
114
	 * Create an incoming share
115
	 *
116
	 * @param Address $ownerAddress
117
	 * @param Address $sharedByAddress
118
	 * @param string $shareWith
119
	 * @param int $remoteId
120
	 * @param string $name
121
	 * @param string $token
122
	 *
123
	 * @return void
124
	 */
125
	public function createShare(Address $ownerAddress,
126
								Address $sharedByAddress,
127
								$shareWith,
128
								$remoteId,
129
								$name,
130
								$token
131
	) {
132
		$owner = $ownerAddress->getUserId();
133
		$shareId = $this->federatedShareProvider->addShare(
134
			$ownerAddress->getOrigin(), $token, $name, $owner, $shareWith, $remoteId
135
		);
136
137
		$this->eventDispatcher->dispatch(
138
			'\OCA\FederatedFileSharing::remote_shareReceived',
139
			new GenericEvent(
140
				null,
141
				[
142
					'name' => $name,
143
					'targetuser' => $sharedByAddress->getCloudId(),
144
					'owner' => $owner,
145
					'sharewith' => $shareWith,
146
					'sharedby' => $sharedByAddress->getUserId(),
147
					'remoteid' => $remoteId
148
				]
149
			)
150
		);
151
		$this->publishActivity(
152
			$shareWith,
153
			Activity::SUBJECT_REMOTE_SHARE_RECEIVED,
154
			[$ownerAddress->getCloudId(), \trim($name, '/')],
155
			'files',
156
			'',
157
			'',
158
			''
159
		);
160
		$link = $this->getActionLink($shareId);
161
		$params = [
162
			$ownerAddress->getCloudId(),
163
			$sharedByAddress->getCloudId(),
164
			\trim($name, '/')
165
		];
166
		$notification = $this->createNotification($shareWith);
167
		$notification->setDateTime(new \DateTime())
168
			->setObject('remote_share', $shareId)
169
			->setSubject('remote_share', $params)
170
			->setMessage('remote_share', $params);
171
		$declineAction = $notification->createAction();
172
		$declineAction->setLabel('decline')
173
			->setLink($link, 'DELETE');
174
		$notification->addAction($declineAction);
175
		$acceptAction = $notification->createAction();
176
		$acceptAction->setLabel('accept')
177
			->setLink($link, 'POST');
178
		$notification->addAction($acceptAction);
179
		$this->notificationManager->notify($notification);
180
	}
181
182
	/**
183
	 * @param IShare $share
184
	 * @param int $remoteId
185
	 * @param string $shareWith
186
	 * @param int|null $permissions - null for OCM 1.0-proposal1
187
	 *
188
	 * @return IShare
189
	 *
190
	 * @throws \OCP\Share\Exceptions\ShareNotFound
191
	 */
192
	public function reShare(IShare $share, $remoteId, $shareWith, $permissions = null) {
193
		if ($permissions !== null) {
194
			$share->setPermissions($share->getPermissions() & $permissions);
195
		}
196
		// the recipient of the initial share is now the initiator for the re-share
197
		$share->setSharedBy($share->getSharedWith());
198
		$share->setSharedWith($shareWith);
199
		$result = $this->federatedShareProvider->create($share);
200
		$this->federatedShareProvider->storeRemoteId(
201
			(int)$result->getId(),
202
			$remoteId
203
		);
204
		return $result;
205
	}
206
207
	/**
208
	 *
209
	 *
210
	 * @param IShare $share
211
	 *
212
	 * @throws \OCP\Files\InvalidPathException
213
	 * @throws \OCP\Files\NotFoundException
214
	 */
215 View Code Duplication
	public function acceptShare(IShare $share) {
216
		$uid = $this->getCorrectUid($share);
217
		$fileId = $share->getNode()->getId();
218
		list($file, $link) = $this->getFile($uid, $fileId);
219
		$this->publishActivity(
220
			$uid,
221
			Activity::SUBJECT_REMOTE_SHARE_ACCEPTED,
222
			[$share->getSharedWith(), \basename($file)],
223
			'files',
224
			$fileId,
225
			$file,
226
			$link
227
		);
228
		$this->notifyRemote($share, [$this->notifications, 'sendAcceptShare']);
229
	}
230
231
	/**
232
	 * Delete declined share and create a activity
233
	 *
234
	 * @param IShare $share
235
	 *
236
	 * @throws \OCP\Files\InvalidPathException
237
	 * @throws \OCP\Files\NotFoundException
238
	 */
239 View Code Duplication
	public function declineShare(IShare $share) {
240
		$this->notifyRemote($share, [$this->notifications, 'sendDeclineShare']);
241
		$uid = $this->getCorrectUid($share);
242
		$fileId = $share->getNode()->getId();
243
		$this->federatedShareProvider->removeShareFromTable($share);
244
		list($file, $link) = $this->getFile($uid, $fileId);
245
		$this->publishActivity(
246
			$uid,
247
			Activity::SUBJECT_REMOTE_SHARE_DECLINED,
248
			[$share->getSharedWith(), \basename($file)],
249
			'files',
250
			$fileId,
251
			$file,
252
			$link
253
		);
254
	}
255
256
	/**
257
	 * Unshare an item from self
258
	 *
259
	 * @param int $id
260
	 * @param string $token
261
	 *
262
	 * @return void
263
	 */
264
	public function unshare($id, $token) {
265
		$shareRow = $this->federatedShareProvider->unshare($id, $token);
266
		if ($shareRow === false) {
267
			return;
268
		}
269
		$ownerAddress = new Address($shareRow['owner'] . '@' . $shareRow['remote']);
270
		$mountpoint = $shareRow['mountpoint'];
271
		$user = $shareRow['user'];
272
		if ($shareRow['accepted']) {
273
			$path = \trim($mountpoint, '/');
274
		} else {
275
			$path = \trim($shareRow['name'], '/');
276
		}
277
		$notification = $this->createNotification($user);
278
		$notification->setObject('remote_share', (int) $shareRow['id']);
279
		$this->notificationManager->markProcessed($notification);
280
		$this->publishActivity(
281
			$user,
282
			Activity::SUBJECT_REMOTE_SHARE_UNSHARED,
283
			[$ownerAddress->getCloudId(), $path],
284
			'files',
285
			'',
286
			'',
287
			''
288
		);
289
	}
290
291
	/**
292
	 * @param IShare $share
293
	 *
294
	 * @return void
295
	 */
296
	public function undoReshare(IShare $share) {
297
		$this->federatedShareProvider->removeShareFromTable($share);
298
	}
299
300
	/**
301
	 * Update permissions
302
	 *
303
	 * @param IShare $share
304
	 * @param string[] $ocmPermissions as ['read', 'write', 'share']
305
	 *
306
	 * @return void
307
	 */
308
	public function updateOcmPermissions(IShare $share, $ocmPermissions) {
309
		$permissions = $this->permissions->toOcPermissions($ocmPermissions);
310
		$this->updatePermissions($share, $permissions);
311
	}
312
313
	/**
314
	 * Update permissions
315
	 *
316
	 * @param IShare $share
317
	 * @param int $permissions
318
	 *
319
	 * @return void
320
	 */
321
	public function updatePermissions(IShare $share, $permissions) {
322
		if ($share->getPermissions() !== $permissions) {
323
			$share->setPermissions($permissions);
324
			$this->federatedShareProvider->update($share);
325
		}
326
	}
327
328
	/**
329
	 * @param IShare $share
330
	 * @param callable $callback
331
	 *
332
	 * @throws \OCP\Share\Exceptions\ShareNotFound
333
	 * @throws \OC\HintException
334
	 */
335
	protected function notifyRemote($share, $callback) {
336
		if ($share->getShareOwner() !== $share->getSharedBy()) {
337
			try {
338
				list(, $remote) = $this->addressHandler->splitUserRemote(
339
					$share->getSharedBy()
340
				);
341
				$remoteId = $this->federatedShareProvider->getRemoteId($share);
342
				$callback($remote, $remoteId, $share->getToken());
343
			} catch (\Exception $e) {
344
				// expected fail if sender is a local user
345
			}
346
		}
347
	}
348
349
	/**
350
	 * Publish a new activity
351
	 *
352
	 * @param string $affectedUser
353
	 * @param string $subject
354
	 * @param array $subjectParams
355
	 * @param string $objectType
356
	 * @param int $objectId
357
	 * @param string $objectName
358
	 * @param string $link
359
	 *
360
	 * @return void
361
	 */
362
	protected function publishActivity($affectedUser,
363
									   $subject,
364
									   $subjectParams,
365
									   $objectType,
366
									   $objectId,
367
									   $objectName,
368
									   $link
369
	) {
370
		$event = $this->activityManager->generateEvent();
371
		$event->setApp(Activity::FILES_SHARING_APP)
372
			->setType(Activity::TYPE_REMOTE_SHARE)
373
			->setAffectedUser($affectedUser)
374
			->setSubject($subject, $subjectParams)
375
			->setObject($objectType, $objectId, $objectName)
376
			->setLink($link);
377
		$this->activityManager->publish($event);
378
	}
379
380
	/**
381
	 * Get a new notification
382
	 *
383
	 * @param string $uid
384
	 *
385
	 * @return \OCP\Notification\INotification
386
	 */
387
	protected function createNotification($uid) {
388
		$notification = $this->notificationManager->createNotification();
389
		$notification->setApp('files_sharing');
390
		$notification->setUser($uid);
391
		return $notification;
392
	}
393
394
	/**
395
	 * @param int $shareId
396
	 * @return string
397
	 */
398
	protected function getActionLink($shareId) {
399
		$urlGenerator = \OC::$server->getURLGenerator();
400
		$link = $urlGenerator->getAbsoluteURL(
401
			$urlGenerator->linkTo('', self::ACTION_URL . $shareId)
402
		);
403
		return $link;
404
	}
405
406
	/**
407
	 * Get file
408
	 *
409
	 * @param string $user
410
	 * @param int $fileSource
411
	 *
412
	 * @return array with internal path of the file and a absolute link to it
413
	 */
414
	protected function getFile($user, $fileSource) {
415
		\OC_Util::setupFS($user);
416
417
		try {
418
			$file = \OC\Files\Filesystem::getPath($fileSource);
419
		} catch (NotFoundException $e) {
420
			$file = null;
421
		}
422
		// FIXME:  use permalink here, see ViewController for reference
423
		$args = \OC\Files\Filesystem::is_dir($file)
424
			? ['dir' => $file]
425
			: ['dir' => \dirname($file), 'scrollto' => $file];
426
		$link = \OCP\Util::linkToAbsolute('files', 'index.php', $args);
427
428
		return [$file, $link];
429
	}
430
431
	/**
432
	 * Check if we are the initiator or the owner of a re-share
433
	 * and return the correct UID
434
	 *
435
	 * @param IShare $share
436
	 *
437
	 * @return string
438
	 */
439
	protected function getCorrectUid(IShare $share) {
440
		if ($this->userManager->userExists($share->getShareOwner())) {
441
			return $share->getShareOwner();
442
		}
443
444
		return $share->getSharedBy();
445
	}
446
}
447