Completed
Pull Request — master (#32303)
by Victor
21:08 queued 10:57
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
			list(, $remote) = $this->addressHandler->splitUserRemote(
338
				$share->getSharedBy()
339
			);
340
			$remoteId = $this->federatedShareProvider->getRemoteId($share);
341
			$callback($remote, $remoteId, $share->getToken());
342
		}
343
	}
344
345
	/**
346
	 * Publish a new activity
347
	 *
348
	 * @param string $affectedUser
349
	 * @param string $subject
350
	 * @param array $subjectParams
351
	 * @param string $objectType
352
	 * @param int $objectId
353
	 * @param string $objectName
354
	 * @param string $link
355
	 *
356
	 * @return void
357
	 */
358
	protected function publishActivity($affectedUser,
359
									   $subject,
360
									   $subjectParams,
361
									   $objectType,
362
									   $objectId,
363
									   $objectName,
364
									   $link
365
	) {
366
		$event = $this->activityManager->generateEvent();
367
		$event->setApp(Activity::FILES_SHARING_APP)
368
			->setType(Activity::TYPE_REMOTE_SHARE)
369
			->setAffectedUser($affectedUser)
370
			->setSubject($subject, $subjectParams)
371
			->setObject($objectType, $objectId, $objectName)
372
			->setLink($link);
373
		$this->activityManager->publish($event);
374
	}
375
376
	/**
377
	 * Get a new notification
378
	 *
379
	 * @param string $uid
380
	 *
381
	 * @return \OCP\Notification\INotification
382
	 */
383
	protected function createNotification($uid) {
384
		$notification = $this->notificationManager->createNotification();
385
		$notification->setApp('files_sharing');
386
		$notification->setUser($uid);
387
		return $notification;
388
	}
389
390
	/**
391
	 * @param int $shareId
392
	 * @return string
393
	 */
394
	protected function getActionLink($shareId) {
395
		$urlGenerator = \OC::$server->getURLGenerator();
396
		$link = $urlGenerator->getAbsoluteURL(
397
			$urlGenerator->linkTo('', self::ACTION_URL . $shareId)
398
		);
399
		return $link;
400
	}
401
402
	/**
403
	 * Get file
404
	 *
405
	 * @param string $user
406
	 * @param int $fileSource
407
	 *
408
	 * @return array with internal path of the file and a absolute link to it
409
	 */
410
	protected function getFile($user, $fileSource) {
411
		\OC_Util::setupFS($user);
412
413
		try {
414
			$file = \OC\Files\Filesystem::getPath($fileSource);
415
		} catch (NotFoundException $e) {
416
			$file = null;
417
		}
418
		// FIXME:  use permalink here, see ViewController for reference
419
		$args = \OC\Files\Filesystem::is_dir($file)
420
			? ['dir' => $file]
421
			: ['dir' => \dirname($file), 'scrollto' => $file];
422
		$link = \OCP\Util::linkToAbsolute('files', 'index.php', $args);
423
424
		return [$file, $link];
425
	}
426
427
	/**
428
	 * Check if we are the initiator or the owner of a re-share
429
	 * and return the correct UID
430
	 *
431
	 * @param IShare $share
432
	 *
433
	 * @return string
434
	 */
435
	protected function getCorrectUid(IShare $share) {
436
		if ($this->userManager->userExists($share->getShareOwner())) {
437
			return $share->getShareOwner();
438
		}
439
440
		return $share->getSharedBy();
441
	}
442
}
443