Completed
Pull Request — master (#196)
by Sander
04:03
created

CredentialController::createCredential()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 40
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 40
rs 8.8571
c 0
b 0
f 0
eloc 35
nc 2
nop 20
ccs 0
cts 32
cp 0
crap 6

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
 * 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\Credential;
15
use OCA\Passman\Db\SharingACL;
16
use OCA\Passman\Service\EncryptService;
17
use OCA\Passman\Service\SettingsService;
18
use OCA\Passman\Utility\NotFoundJSONResponse;
19
use OCP\AppFramework\Db\DoesNotExistException;
20
use OCP\AppFramework\Http;
21
use OCP\AppFramework\Http\DataResponse;
22
use OCP\IRequest;
23
use OCP\AppFramework\Http\JSONResponse;
24
use OCP\AppFramework\ApiController;
25
use OCA\Passman\Service\CredentialService;
26
use OCA\Passman\Activity;
27
use OCA\Passman\Service\ActivityService;
28
use OCA\Passman\Service\CredentialRevisionService;
29
use OCA\Passman\Service\ShareService;
30
31
32
class CredentialController extends ApiController {
33
	private $userId;
34
	private $credentialService;
35
	private $activityService;
36
	private $credentialRevisionService;
37
	private $sharingService;
38
	private $settings;
39
40
	public function __construct($AppName,
41
								IRequest $request,
42
								$userId,
43
								CredentialService $credentialService,
44
								ActivityService $activityService,
45
								CredentialRevisionService $credentialRevisionService,
46
								ShareService $sharingService,
47
								SettingsService $settings
48
49
	) {
50
		parent::__construct($AppName, $request);
51
		$this->userId = $userId;
52
		$this->credentialService = $credentialService;
53
		$this->activityService = $activityService;
54
		$this->credentialRevisionService = $credentialRevisionService;
55
		$this->sharingService = $sharingService;
56
		$this->settings = $settings;
57
	}
58
59
60
	/**
61
	 * @NoAdminRequired
62
	 * @NoCSRFRequired
63
	 */
64
	public function createCredential($changed, $created,
65
									 $credential_id, $custom_fields, $delete_time,
66
									 $description, $email, $expire_time, $favicon, $files, $guid,
67
									 $hidden, $label, $otp, $password, $renew_interval,
68
									 $tags, $url, $username, $vault_id) {
69
		$credential = array(
70
			'credential_id' => $credential_id,
71
			'guid' => $guid,
72
			'user_id' => $this->userId,
73
			'vault_id' => $vault_id,
74
			'label' => $label,
75
			'description' => $description,
76
			'created' => $created,
77
			'changed' => $changed,
78
			'tags' => $tags,
79
			'email' => $email,
80
			'username' => $username,
81
			'password' => $password,
82
			'url' => $url,
83
			'favicon' => $favicon,
84
			'renew_interval' => $renew_interval,
85
			'expire_time' => $expire_time,
86
			'delete_time' => $delete_time,
87
			'files' => $files,
88
			'custom_fields' => $custom_fields,
89
			'otp' => $otp,
90
			'hidden' => $hidden,
91
92
		);
93
94
		$credential = $this->credentialService->createCredential($credential);
95
		$link = ''; // @TODO create direct link to credential
96
		if (!$credential->getHidden()) {
97
			$this->activityService->add(
98
				Activity::SUBJECT_ITEM_CREATED_SELF, array($label, $this->userId),
99
				'', array(),
100
				$link, $this->userId, Activity::TYPE_ITEM_ACTION);
101
		}
102
		return new JSONResponse($credential);
103
	}
104
105
	/**
106
	 * @NoAdminRequired
107
	 * @NoCSRFRequired
108
	 */
109
	public function getCredential($credential_guid) {
110
		$credential = $this->credentialService->getCredentialByGUID($credential_guid, $this->userId);
111
		return new JSONResponse($credential);
112
	}
113
114
	/**
115
	 * @NoAdminRequired
116
	 * @NoCSRFRequired
117
	 */
118
	public function updateCredential($changed, $created,
119
									 $credential_id, $custom_fields, $delete_time, $credential_guid,
120
									 $description, $email, $expire_time, $favicon, $files, $guid,
121
									 $hidden, $label, $otp, $password, $renew_interval,
122
									 $tags, $url, $username, $vault_id, $revision_created, $shared_key, $acl, $unshare_action, $set_share_key, $skip_revision) {
123
124
125
		$storedCredential = $this->credentialService->getCredentialByGUID($credential_guid);
126
127
		$credential = array(
128
			'credential_id' => $credential_id,
129
			'guid' => $guid,
130
			'label' => $label,
131
			'description' => $description,
132
			'created' => $created,
133
			'changed' => $changed,
134
			'vault_id' => $vault_id,
135
			'tags' => $tags,
136
			'email' => $email,
137
			'username' => $username,
138
			'password' => $password,
139
			'url' => $url,
140
			'favicon' => $favicon,
141
			'renew_interval' => $renew_interval,
142
			'expire_time' => $expire_time,
143
			'files' => $files,
144
			'custom_fields' => $custom_fields,
145
			'delete_time' => $delete_time,
146
			'hidden' => $hidden,
147
			'otp' => $otp,
148
			'user_id' => $storedCredential->getUserId()
149
		);
150
151
152
		if (!hash_equals($storedCredential->getUserId(), $this->userId)) {
153
			$acl = $this->sharingService->getCredentialAclForUser($this->userId, $storedCredential->getGuid());
154
			if ($acl->hasPermission(SharingACL::WRITE)) {
155
				$credential['shared_key'] = $storedCredential->getSharedKey();
156
			} else {
157
				return new DataResponse(['msg' => 'Not authorized'], Http::STATUS_UNAUTHORIZED);
158
			}
159
			if (!$this->settings->isEnabled('user_sharing_enabled')) {
160
				return new DataResponse(['msg' => 'Not authorized'], Http::STATUS_UNAUTHORIZED);
161
			}
162
		}
163
164
165
		$link = ''; // @TODO create direct link to credential
166
		if ($revision_created) {
167
			$activity = 'item_apply_revision';
168
			$this->activityService->add(
169
				$activity . '_self', array($label, $this->userId, $revision_created),
170
				'', array(),
171
				$link, $this->userId, Activity::TYPE_ITEM_ACTION);
172
		} else if (($storedCredential->getDeleteTime() === 0) && (int)$delete_time > 0) {
173
			$activity = 'item_deleted';
174
			$this->activityService->add(
175
				$activity . '_self', array($label, $this->userId),
176
				'', array(),
177
				$link, $this->userId, Activity::TYPE_ITEM_ACTION);
178
		} else if (($storedCredential->getDeleteTime() > 0) && (int)$delete_time === 0) {
179
			$activity = 'item_recovered';
180
			$this->activityService->add(
181
				$activity . '_self', array($label, $this->userId),
182
				'', array(),
183
				$link, $this->userId, Activity::TYPE_ITEM_ACTION);
184
		} else if ($label !== $storedCredential->getLabel()) {
185
			$activity = 'item_renamed';
186
			$this->activityService->add(
187
				$activity . '_self', array($storedCredential->getLabel(), $label, $this->userId),
188
				'', array(),
189
				$link, $this->userId, Activity::TYPE_ITEM_RENAMED);
190
		} else {
191
			$activity = 'item_edited';
192
			$this->activityService->add(
193
				$activity . '_self', array($label, $this->userId),
194
				'', array(),
195
				$link, $this->userId, Activity::TYPE_ITEM_ACTION);
196
		}
197
		$acl_list = null;
198
199
		try {
200
			$acl_list = $this->sharingService->getCredentialAclList($storedCredential->getGuid());
201
		} catch (\Exception $exception) {
202
			// Just check if we have an acl list
203
		}
204
		if (!empty($acl_list)) {
205
			$params = array();
206
			switch ($activity) {
207
				case 'item_recovered':
208
				case 'item_deleted':
209
				case 'item_edited':
210
					$params = array($credential['label'], $this->userId);
211
					break;
212
				case 'item_apply_revision':
213
					$params = array($credential['label'], $this->userId, $revision_created);
214
					break;
215
				case 'item_renamed':
216
					$params = array($storedCredential->getLabel(), $label, $this->userId);
217
					break;
218
			}
219
220
			foreach ($acl_list as $sharingACL) {
221
				$target_user = $sharingACL->getUserId();
222
				if ($target_user === $this->userId) {
223
					continue;
224
				}
225
				$this->activityService->add(
226
					$activity, $params,
227
					'', array(),
228
					$link, $target_user, Activity::TYPE_ITEM_ACTION);
229
			}
230
			if (!hash_equals($this->userId, $storedCredential->getUserId())) {
231
				$this->activityService->add(
232
					$activity, $params,
233
					'', array(),
234
					$link, $storedCredential->getUserId(), Activity::TYPE_ITEM_ACTION);
235
			}
236
		}
237
		if ($set_share_key === true) {
238
			$storedCredential->setSharedKey($shared_key);
239
			$credential['shared_key'] = $shared_key;
240
		}
241
		if ($unshare_action === true) {
242
			$storedCredential->setSharedKey('');
243
			$credential['shared_key'] = '';
244
		}
245
246
		if (!isset($credential['shared_key'])) {
247
			$credential['shared_key'] = $storedCredential->getSharedKey();
248
		}
249
250
		if (!$skip_revision) {
251
			$this->credentialRevisionService->createRevision($storedCredential, $storedCredential->getUserId(), $credential_id, $this->userId);
252
		}
253
254
		$credential = $this->credentialService->updateCredential($credential);
255
256
		return new JSONResponse($credential);
257
	}
258
259
	/**
260
	 * @NoAdminRequired
261
	 * @NoCSRFRequired
262
	 */
263
	public function deleteCredential($credential_guid) {
264
		try {
265
			$credential = $this->credentialService->getCredentialByGUID($credential_guid, $this->userId);
266
		} catch (\Exception $e) {
267
			return new NotFoundJSONResponse();
268
		}
269
		if ($credential) {
270
			$result = $this->credentialService->deleteCredential($credential);
271
			$this->deleteCredentialParts($credential);
272
		} else {
273
			$result = false;
274
		}
275
		return new JSONResponse($result);
276
	}
277
278
	/**
279
	 * Delete leftovers from a credential
280
	 * @param Credential $credential
281
	 */
282
	private function deleteCredentialParts(Credential $credential) {
283
		$this->activityService->add(
284
			'item_destroyed_self', array($credential->getLabel()),
285
			'', array(),
286
			'', $this->userId, Activity::TYPE_ITEM_ACTION);
287
		$this->sharingService->unshareCredential($credential->getGuid());
288
		foreach ($this->credentialRevisionService->getRevisions($credential->getId()) as $revision) {
289
			$this->credentialRevisionService->deleteRevision($revision->getId(), $this->userId);
290
		}
291
	}
292
293
	/**
294
	 * @NoAdminRequired
295
	 * @NoCSRFRequired
296
	 */
297
	public function getRevision($credential_guid) {
298
		try {
299
			$credential = $this->credentialService->getCredentialByGUID($credential_guid);
300
		} catch (\Exception $ex) {
301
			return new NotFoundJSONResponse();
302
		}
303
		// If the request was made by the owner of the credential
304
		if ($this->userId === $credential->getUserId()) {
305
			$result = $this->credentialRevisionService->getRevisions($credential->getId(), $this->userId);
306
		} else {
307
			$acl = $this->sharingService->getACL($this->userId, $credential_guid);
308
			if ($acl->hasPermission(SharingACL::HISTORY)) {
309
				$result = $this->credentialRevisionService->getRevisions($credential->getId());
310
			} else {
311
				return new NotFoundJSONResponse();
312
			}
313
		}
314
315
		return new JSONResponse($result);
316
	}
317
318
	/**
319
	 * @NoAdminRequired
320
	 * @NoCSRFRequired
321
	 */
322
	public function deleteRevision($credential_id, $revision_id) {
323
		$result = $this->credentialRevisionService->deleteRevision($revision_id, $this->userId);
324
		return new JSONResponse($result);
325
	}
326
327
	/**
328
	 * @NoAdminRequired
329
	 * @NoCSRFRequired
330
	 */
331
	public function updateRevision($credential_guid, $revision_id, $credential_data) {
332
		$revision = null;
333
		try {
334
			$this->credentialService->getCredentialByGUID($credential_guid, $this->userId);
335
		} catch (\Exception $e) {
336
			return new NotFoundJSONResponse();
337
		}
338
339
		try {
340
			$revision = $this->credentialRevisionService->getRevision($revision_id);
341
		} catch (\Exception $exception) {
342
			return new NotFoundJSONResponse();
343
		}
344
345
		$revision->setCredentialData($credential_data);
346
347
		$this->credentialRevisionService->updateRevision($revision);
348
		return new JSONResponse(array());
349
	}
350
}