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

CredentialController::deleteCredentialParts()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 10
ccs 0
cts 10
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
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
}