Completed
Push — master ( 641a91...fc9f6a )
by
unknown
10:16
created

ShareController::deleteShareRequest()   A

Complexity

Conditions 2
Paths 10

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 28
rs 9.472
c 0
b 0
f 0
nc 10
nop 1
ccs 0
cts 18
cp 0
crap 6
1
<?php
2
/**
3
 * Nextcloud - passman
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Sander Brand <[email protected]>
9
 * @copyright Sander Brand 2016
10
 */
11
12
namespace OCA\Passman\Controller;
13
14
use OCA\Passman\Db\SharingACL;
15
use OCA\Passman\Db\Vault;
16
use OCA\Passman\Service\CredentialService;
17
use OCA\Passman\Service\FileService;
18
use OCA\Passman\Service\NotificationService;
19
use OCA\Passman\Service\SettingsService;
20
use OCA\Passman\Service\ShareService;
21
use OCA\Passman\Utility\NotFoundJSONResponse;
22
use OCA\Passman\Utility\Utils;
23
use OCP\AppFramework\Http\NotFoundResponse;
24
use OCP\IRequest;
25
use OCP\AppFramework\Http\JSONResponse;
26
use OCP\AppFramework\ApiController;
27
28
use OCP\IGroupManager;
29
use OCP\IUserManager;
30
31
use OCA\Passman\Service\VaultService;
32
use OCA\Passman\Service\ActivityService;
33
use OCA\Passman\Activity;
34
35
36
class ShareController extends ApiController {
37
	private $userId;
38
	private $activityService;
39
	private $groupManager;
40
	private $userManager;
41
	private $vaultService;
42
	private $shareService;
43
	private $credentialService;
44
	private $notificationService;
45
	private $fileService;
46
	private $settings;
47
48
	private $limit = 50;
49
	private $offset = 0;
50
51
	public function __construct($AppName,
52
								IRequest $request,
53
								$UserId,
54
								IGroupManager $groupManager,
55
								IUserManager $userManager,
56
								ActivityService $activityService,
57
								VaultService $vaultService,
58
								ShareService $shareService,
59
								CredentialService $credentialService,
60
								NotificationService $notificationService,
61
								FileService $fileService,
62
								SettingsService $config
63
	) {
64
		parent::__construct(
65
			$AppName,
66
			$request,
67
			'GET, POST, DELETE, PUT, PATCH, OPTIONS',
68
			'Authorization, Content-Type, Accept',
69
			86400);
70
71
		$this->userId = $UserId;
72
		$this->userManager = $userManager;
73
		$this->groupManager = $groupManager;
74
		$this->activityService = $activityService;
75
		$this->vaultService = $vaultService;
76
		$this->shareService = $shareService;
77
		$this->credentialService = $credentialService;
78
		$this->notificationService = $notificationService;
79
		$this->fileService = $fileService;
80
		$this->settings = $config;
81
	}
82
83
84
	/**
85
	 * @param $item_id
86
	 * @param $item_guid
87
	 * @param $permissions
88
	 * @param $expire_timestamp
89
	 * @NoAdminRequired
90
	 * @NoCSRFRequired
91
	 */
92
	public function createPublicShare($item_id, $item_guid, $permissions, $expire_timestamp, $expire_views) {
93
		try {
94
			$credential = $this->credentialService->getCredentialByGUID($item_guid);
95
		} catch (\Exception $exception) {
96
			return new NotFoundResponse();
97
		}
98
99
		try {
100
			$acl = $this->shareService->getACL(null, $item_guid);
101
		} catch (\Exception $exception) {
102
			$acl = new SharingACL();
103
		}
104
105
106
		$acl->setItemId($item_id);
107
		$acl->setItemGuid($item_guid);
108
		$acl->setPermissions($permissions);
109
		$acl->setExpire($expire_timestamp);
110
		$acl->setExpireViews($expire_views);
111
		if (!$acl->getId()) {
112
			$this->shareService->createACLEntry($acl);
113
114
			$this->activityService->add(
115
				'item_shared_publicly', [$credential->getLabel()],
116
				'', array(),
117
				'', $this->userId->getUID(), Activity::TYPE_ITEM_SHARED);
118
		} else {
119
			$this->shareService->updateCredentialACL($acl);
120
		}
121
122
	}
123
124
	/**
125
	 * @NoAdminRequired
126
	 * @NoCSRFRequired
127
	 */
128
	public function applyIntermediateShare($item_id, $item_guid, $vaults, $permissions) {
129
		/**
130
		 * Assemble notification
131
		 */
132
		//@TODO add expire_time
133
		//@TODO add expire_views
134
		$credential = $this->credentialService->getCredentialById($item_id, $this->userId->getUID());
135
		$credential_owner = $credential->getUserId();
136
137
		$first_vault = $vaults[0];
138
		try {
139
			$shareRequests = $this->shareService->getPendingShareRequestsForCredential($item_guid, $first_vault['user_id']);
140
			if (count($shareRequests) > 0) {
141
				return new JSONResponse(array('error' => 'User got already pending requests'));
142
			}
143
		} catch (\Exception $exception) {
144
			// no need to catch this
145
		}
146
147
		$acl = null;
148
		try {
149
			$acl = $this->shareService->getCredentialAclForUser($first_vault['user_id'], $item_guid);
150
		} catch (\Exception $exception) {
151
			// no need to catch this
152
		}
153
154
		if ($acl) {
155
			return new JSONResponse(array('error' => 'User got already this credential'));
156
		}
157
158
		$result = $this->shareService->createBulkRequests($item_id, $item_guid, $vaults, $permissions, $credential_owner);
159
		if ($credential) {
160
			$processed_users = array();
161
			foreach ($result as $vault) {
162
				if (!in_array($vault->getTargetUserId(), $processed_users)) {
163
					$target_user = $vault->getTargetUserId();
164
					$notification = array(
165
						'from_user' => ucfirst($this->userId->getDisplayName()),
166
						'credential_label' => $credential->getLabel(),
167
						'credential_id' => $credential->getId(),
168
						'item_id' => $credential->getId(),
169
						'target_user' => $target_user,
170
						'req_id' => $vault->getId()
171
					);
172
					$this->notificationService->credentialSharedNotification(
173
						$notification
174
					);
175
					array_push($processed_users, $target_user);
176
177
					$this->activityService->add(
178
						'item_shared', [$credential->getLabel(), $target_user],
179
						'', array(),
180
						'', $this->userId->getUID(), Activity::TYPE_ITEM_SHARED);
181
182
183
					$this->activityService->add(
184
						'item_share_received', [$credential->getLabel(), $this->userId->getUID()],
185
						'', array(),
186
						'', $target_user, Activity::TYPE_ITEM_SHARED);
187
				}
188
			}
189
		}
190
191
192
		return new JSONResponse($result);
193
	}
194
195
	/**
196
	 * @NoAdminRequired
197
	 * @NoCSRFRequired
198
	 */
199
	public function searchUsers($search) {
200
		$users = array();
201
		$usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
202
203
		foreach ($usersTmp as $user) {
204
			if ($this->userId->getUID() !== $user->getUID() && count($this->vaultService->getByUser($user->getUID())) >= 1) {
205
				$users[] = array(
206
					'text' => $user->getDisplayName(),
207
					'uid' => $user->getUID(),
208
					'type' => 'user'
209
				);
210
			}
211
		}
212
		return $users;
213
	}
214
215
216
	/**
217
	 * @NoAdminRequired
218
	 * @NoCSRFRequired
219
	 */
220
	public function unshareCredential($item_guid) {
221
		$this->shareService->unshareCredential($item_guid);
222
		return new JSONResponse(array('result' => true));
223
	}
224
225
226
	public function unshareCredentialFromUser($item_guid, $user_id) {
227
		$acl = null;
228
		$sr = null;
229
		try {
230
			$acl = $this->shareService->getCredentialAclForUser($user_id, $item_guid);
231
		} catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
232
233
		}
234
		try {
235
			$sr = array_pop($this->shareService->getPendingShareRequestsForCredential($item_guid, $user_id));
0 ignored issues
show
Bug introduced by
$this->shareService->get...l($item_guid, $user_id) cannot be passed to array_pop() as the parameter $array expects a reference.
Loading history...
236
		} catch (\Exception $e) {
237
			// no need to catch this
238
		}
239
240 View Code Duplication
		if ($sr) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
241
			$this->shareService->cleanItemRequestsForUser($sr);
242
			$manager = \OC::$server->getNotificationManager();
243
			$notification = $manager->createNotification();
244
			$notification->setApp('passman')
245
				->setObject('passman_share_request', $sr->getId())
246
				->setUser($user_id);
247
			$manager->markProcessed($notification);
248
		}
249
		if ($acl) {
250
			$this->shareService->deleteShareACL($acl);
251
		}
252
		return new JSONResponse(array('result' => true));
253
	}
254
255
	/**
256
	 * @NoAdminRequired
257
	 * @NoCSRFRequired
258
	 */
259
	public function search($search) {
260
		$user_search = $this->searchUsers($search);
261
		return new JSONResponse($user_search);
262
	}
263
264
265
	/**
266
	 * @NoAdminRequired
267
	 * @NoCSRFRequired
268
	 */
269
	public function getVaultsByUser($user_id) {
270
		$user_vaults = $this->vaultService->getByUser($user_id);
271
		$result = array();
272
		foreach ($user_vaults as $vault) {
273
			array_push($result,
274
				array(
275
					'vault_id' => $vault->getId(),
276
					'guid' => $vault->getGuid(),
277
					'public_sharing_key' => $vault->getPublicSharingKey(),
278
					'user_id' => $user_id,
279
				));
280
		}
281
		return new JSONResponse($result);
282
	}
283
284
	/**
285
	 * @NoAdminRequired
286
	 * @NoCSRFRequired
287
	 */
288
	public function savePendingRequest($item_guid, $target_vault_guid, $final_shared_key) {
289
		try {
290
			$sr = $this->shareService->getRequestByGuid($item_guid, $target_vault_guid);
291
		} catch (\Exception $ex) {
292
			return new NotFoundResponse();
293
		}
294
295
		$manager = \OC::$server->getNotificationManager();
296
		$notification = $manager->createNotification();
297
		$notification->setApp('passman')
298
			->setObject('passman_share_request', $sr->getId())
299
			->setUser($this->userId->getUID());
300
		$manager->markProcessed($notification);
301
302
		$notification = array(
303
			'from_user' => ucfirst($this->userId->getDisplayName()),
304
			'credential_label' => $this->credentialService->getCredentialLabelById($sr->getItemId())->getLabel(),
305
			'target_user' => $sr->getFromUserId(),
306
			'req_id' => $sr->getId()
307
		);
308
309
		$this->notificationService->credentialAcceptedSharedNotification(
310
			$notification
311
		);
312
313
314
		$this->shareService->applyShare($item_guid, $target_vault_guid, $final_shared_key);
315
	}
316
317
	/**
318
	 * @NoAdminRequired
319
	 * @NoCSRFRequired
320
	 */
321
	public function getPendingRequests() {
322
		try {
323
			$requests = $this->shareService->getUserPendingRequests($this->userId->getUID());
324
			$results = array();
325
			foreach ($requests as $request) {
326
				$result = $request->jsonSerialize();
327
				$c = $this->credentialService->getCredentialLabelById($request->getItemId());
328
				$result['credential_label'] = $c->getLabel();
329
				array_push($results, $result);
330
			}
331
			return new JSONResponse($results);
332
		} catch (\Exception $ex) {
333
			return new NotFoundResponse();
334
		}
335
	}
336
337
	/**
338
	 * @param $item_guid
339
	 * @return JSONResponse
340
	 * @NoAdminRequired
341
	 * @NoCSRFRequired
342
	 */
343
	public function getRevisions($item_guid) {
344
		try {
345
			return new JSONResponse($this->shareService->getItemHistory($this->userId, $item_guid));
346
		} catch (\Exception $ex) {
347
			return new NotFoundJSONResponse();
348
		}
349
	}
350
351
	/**
352
	 * Obtains the list of credentials shared with this vault
353
	 *
354
	 * @NoAdminRequired
355
	 * @NoCSRFRequired
356
	 */
357
	public function getVaultItems($vault_guid) {
358
		try {
359
			return new JSONResponse($this->shareService->getSharedItems($this->userId->getUID(), $vault_guid));
360
		} catch (\Exception $ex) {
361
			return new NotFoundResponse();
362
		}
363
	}
364
365
	/**
366
	 * @param $share_request_id
367
	 * @return JSONResponse
368
	 * @NoAdminRequired
369
	 * @NoCSRFRequired
370
	 */
371
	public function deleteShareRequest($share_request_id) {
372
		try {
373
374
			$sr = $this->shareService->getShareRequestById($share_request_id);
375
			$notification = array(
376
				'from_user' => ucfirst($this->userId->getDisplayName()),
377
				'credential_label' => $this->credentialService->getCredentialLabelById($sr->getItemId())->getLabel(),
378
				'target_user' => $sr->getFromUserId(),
379
				'req_id' => $sr->getId()
380
			);
381
			$this->notificationService->credentialDeclinedSharedNotification(
382
				$notification
383
			);
384
385
386
			$manager = \OC::$server->getNotificationManager();
387
			$notification = $manager->createNotification();
388
			$notification->setApp('passman')
389
				->setObject('passman_share_request', $share_request_id)
390
				->setUser($this->userId->getUID());
391
			$manager->markProcessed($notification);
392
393
			$this->shareService->cleanItemRequestsForUser($sr);
394
			return new JSONResponse(array('result' => true));
395
		} catch (\Exception $ex) {
396
			return new NotFoundJSONResponse();
397
		}
398
	}
399
400
	/**
401
	 * @param $credential_guid
402
	 * @return JSONResponse
403
	 * @NoAdminRequired
404
	 * @NoCSRFRequired
405
	 * @PublicPage
406
	 */
407
	public function getPublicCredentialData($credential_guid) {
408
		//@TODO Check expire date
409
		$acl = $this->shareService->getACL(null, $credential_guid);
410
411
		if ($acl->getExpire() > 0 && Utils::getTime() > $acl->getExpire()) {
412
			return new NotFoundJSONResponse();
413
		}
414
415
		$views = $acl->getExpireViews();
416
		if ($views === 0) {
417
			return new NotFoundJSONResponse();
418
		} else if ($views !== -1) {
419
			$views--;
420
			$acl->setExpireViews($views);
421
			$this->shareService->updateCredentialACL($acl);
422
		}
423
424
425
		try {
426
			$credential = $this->shareService->getSharedItem(null, $credential_guid);
427
			return new JSONResponse($credential);
428
		} catch (\Exception $ex) {
429
			return new NotFoundJSONResponse();
430
		}
431
	}
432
433
	/**
434
	 * @param $item_guid
435
	 * @return JSONResponse
436
	 * @NoAdminRequired
437
	 * @NoCSRFRequired
438
	 */
439
	public function getItemAcl($item_guid) {
440
		$acl = $this->shareService->getCredentialAclList($item_guid);
441
		$pending = $this->shareService->getCredentialPendingAclList($item_guid);
442
		try {
443
			$credential = $this->credentialService->getCredentialByGUID($item_guid);
444
			if ($credential->getUserId() === $this->userId->getUID()) {
445
				foreach ($pending as &$item) {
446
					$item = $item->asACLJson();
447
				}
448
				$acl = array_merge($acl, $pending);
449
				return new JSONResponse($acl);
450
			} else {
451
				return new NotFoundResponse();
452
			}
453
		} catch (\Exception $ex) {
454
			return new JSONResponse(array());
455
		}
456
	}
457
458
	/**
459
	 * @param $item_guid
460
	 * @param $file_guid
461
	 * @NoAdminRequired
462
	 * @PublicPage
463
	 * @return mixed
464
	 * @return NotFoundJSONResponse
465
	 */
466
	public function getFile($item_guid, $file_guid) {
467
		try {
468
			$credential = $this->credentialService->getCredentialByGUID($item_guid);
469
		} catch (\Exception $e) {
470
			return new NotFoundJSONResponse();
471
		}
472
		$userId = ($this->userId) ? $this->userId->getUID() : null;
473
		$acl = $this->shareService->getACL($userId, $credential->getGuid());
474
		if (!$acl->hasPermission(SharingACL::FILES)) {
475
			return new NotFoundJSONResponse();
476
		} else {
477
			return $this->fileService->getFileByGuid($file_guid);
478
		}
479
	}
480
481
	/**
482
	 * @param $item_guid
483
	 * @param  $user_id
484
	 * @param $permission
485
	 * @return JSONResponse
486
	 * @NoAdminRequired
487
	 * @NoCSRFRequired
488
	 */
489
	public function updateSharedCredentialACL($item_guid, $user_id, $permission) {
490
		try {
491
			$credential = $this->credentialService->getCredentialByGUID($item_guid);
492
		} catch (\Exception $exception) {
493
			return new NotFoundJSONResponse();
494
		}
495
		if ($this->userId->getUID() === $credential->getUserId()) {
496
			$acl = null;
497
			try {
498
				$acl = $this->shareService->getACL($user_id, $item_guid);
499
				$acl->setPermissions($permission);
500
				return $this->shareService->updateCredentialACL($acl);
501
			} catch (\Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
502
503
			}
504
505
			if ($acl === null) {
506
				$this->shareService->updatePendingShareRequestsForCredential($item_guid, $user_id, $permission);
507
			}
508
509
		}
510
	}
511
}