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