Failed Conditions
Pull Request — master (#682)
by
unknown
09:41
created

lib/Service/ShareService.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Nextcloud - passman
4
 *
5
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
6
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Passman\Service;
25
26
27
use OCA\Passman\Db\CredentialMapper;
28
use OCA\Passman\Db\CredentialRevision;
29
use OCA\Passman\Db\ShareRequest;
30
use OCA\Passman\Db\ShareRequestMapper;
31
use OCA\Passman\Db\SharingACL;
32
use OCA\Passman\Db\SharingACLMapper;
33
use OCA\Passman\Utility\Utils;
34
use OCP\AppFramework\Db\DoesNotExistException;
35
use OCP\AppFramework\Db\Entity;
36
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
37
use OCP\DB\Exception;
38
use OCP\DB\IResult;
39
use OCP\Notification\IManager;
40
41
class ShareService {
42
	private SharingACLMapper $sharingACL;
0 ignored issues
show
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
43
	private ShareRequestMapper $shareRequest;
44
	private CredentialMapper $credential;
45
	private CredentialRevisionService $revisions;
46
	private EncryptService $encryptService;
47
	private IManager $IManager;
48
49
50
	public function __construct(
51
		SharingACLMapper $sharingACL,
52
		ShareRequestMapper $shareRequest,
53
		CredentialMapper $credentials,
54
		CredentialRevisionService $revisions,
55
		EncryptService $encryptService,
56
		IManager $IManager
57
	) {
58
		$this->sharingACL = $sharingACL;
59
		$this->shareRequest = $shareRequest;
60
		$this->credential = $credentials;
61
		$this->revisions = $revisions;
62
		$this->encryptService = $encryptService;
63
		$this->IManager = $IManager;
64
	}
65
66
	/**
67
	 * Creates requests for all the items on the request array of objects.
68
	 * This array must follow this spec:
69
	 *      user_id:    The target user id
70
	 *      vault_id:   The id of the target vault
71
	 *      guid:       The guid of the target vault
72
	 *      key:        The shared key cyphered with the target vault RSA public key
73
	 *
74
	 * @param $target_item_id   string      The shared item ID
75
	 * @param $target_item_guid string      The shared item GUID
76
	 * @param $request_array    array
77
	 * @param $permissions      integer     Must be created with a bitmask from options on the ShareRequest class
78
	 * @return array                        Array of sharing requests
79
	 */
80
	public function createBulkRequests($target_item_id, $target_item_guid, $request_array, $permissions, $credential_owner) {
81
		$created = Utils::getTime();
82
		$requests = array();
83
		foreach ($request_array as $req) {
84
			$t = new ShareRequest();
85
			$t->setItemId($target_item_id);
86
			$t->setItemGuid($target_item_guid);
87
			$t->setTargetUserId($req['user_id']);
88
			$t->setTargetVaultId($req['vault_id']);
89
			$t->setTargetVaultGuid($req['guid']);
90
			$t->setSharedKey($req['key']);
91
			$t->setPermissions($permissions);
92
			$t->setCreated($created);
93
			$t->setFromUserId($credential_owner);
94
			array_push($requests, $this->shareRequest->createRequest($t));
95
		}
96
		return $requests;
97
	}
98
99
	/**
100
	 * @param SharingACL $acl
101
	 * @return Entity
102
	 */
103
	public function createACLEntry(SharingACL $acl) {
104
		if ($acl->getCreated() === null) $acl->setCreated((new \DateTime())->getTimestamp());
105
		return $this->sharingACL->createACLEntry($acl);
106
	}
107
108
	/**
109
	 * Applies the given share, defaults to no expire
110
	 *
111
	 * @param string $item_guid
112
	 * @param string $target_vault_guid
113
	 * @param string $final_shared_key
114
	 * @throws DoesNotExistException
115
	 * @throws Exception
116
	 * @throws MultipleObjectsReturnedException
117
	 */
118
	public function applyShare(string $item_guid, string $target_vault_guid, string $final_shared_key) {
119
		$request = $this->shareRequest->getRequestByItemAndVaultGuid($item_guid, $target_vault_guid);
120
		$permissions = $request->getPermissions();
121
122
		$acl = new SharingACL();
123
		$acl->setItemId($request->getItemId());
124
		$acl->setItemGuid($request->getItemGuid());
125
		$acl->setUserId($request->getTargetUserId());
126
		$acl->setCreated($request->getCreated());
127
		$acl->setExpire(0);
128
		$acl->setPermissions($permissions);
129
		$acl->setVaultId($request->getTargetVaultId());
130
		$acl->setVaultGuid($request->getTargetVaultGuid());
131
		$acl->setSharedKey($final_shared_key);
132
133
		$this->sharingACL->createACLEntry($acl);
134
		$this->shareRequest->cleanItemRequestsForUser($request->getItemId(), $request->getTargetUserId());
135
	}
136
137
	/**
138
	 * Obtains pending requests for the given user ID
139
	 *
140
	 * @param string $user_id
141
	 * @return ShareRequest[]
142
	 */
143
	public function getUserPendingRequests(string $user_id) {
144
		return $this->shareRequest->getUserPendingRequests($user_id);
145
	}
146
147
	/**
148
	 * Get shared credentials from a user
149
	 *
150
	 * @param string $user_id
151
	 * @param string $vault_guid
152
	 * @return array
153
	 * @throws DoesNotExistException
154
	 * @throws MultipleObjectsReturnedException
155
	 */
156
	public function getSharedItems(string $user_id, string $vault_guid) {
157
		$entries = $this->sharingACL->getVaultEntries($user_id, $vault_guid);
158
159
		$return = [];
160
		foreach ($entries as $entry) {
161
			// Check if the user can read the credential, probably unnecesary, but just to be sure
162
			if (!$entry->hasPermission(SharingACL::READ)) continue;
163
			$tmp = $entry->jsonSerialize();
164
			$credential = $this->credential->getCredentialById($entry->getItemId());
165
			$credential = $this->encryptService->decryptCredential($credential);
166
			$tmp['credential_data'] = $credential->jsonSerialize();
167
168
			if (!$entry->hasPermission(SharingACL::FILES)) unset($tmp['credential_data']['files']);
169
			unset($tmp['credential_data']['shared_key']);
170
			$return[] = $tmp;
171
		}
172
		return $return;
173
	}
174
175
	/**
176
	 * Gets the acl for a given item guid
177
	 *
178
	 * @param string $user_id
179
	 * @param string $item_guid
180
	 * @return SharingACL
181
	 */
182
	public function getACL(string $user_id, string $item_guid) {
183
		return $this->sharingACL->getItemACL($user_id, $item_guid);
184
	}
185
186
	/**
187
	 * @param string $user_id
188
	 * @param string $item_guid
189
	 * @return array|mixed
190
	 * @throws DoesNotExistException
191
	 * @throws MultipleObjectsReturnedException
192
	 */
193
	public function getSharedItem(string $user_id, string $item_guid) {
194
		$acl = $this->sharingACL->getItemACL($user_id, $item_guid);
195
196
		// Check if the user can read the credential, probably unnecesary, but just to be sure
197
		if (!$acl->hasPermission(SharingACL::READ)) throw new DoesNotExistException("Item not found or wrong access level");
198
199
		$tmp = $acl->jsonSerialize();
200
		$credential = $this->credential->getCredentialById($acl->getItemId());
201
		$credential = $this->encryptService->decryptCredential($credential);
202
203
		$tmp['credential_data'] = $credential->jsonSerialize();
204
205
		if (!$acl->hasPermission(SharingACL::FILES)) unset($tmp['credential_data']['files']);
206
		unset($tmp['credential_data']['shared_key']);
207
208
		return $tmp;
209
	}
210
211
	/**
212
	 * Gets history from the given item checking the user's permissions to access it
213
	 *
214
	 * @param string $user_id
215
	 * @param string $item_guid
216
	 * @return CredentialRevision[]
217
	 */
218
	public function getItemHistory(string $user_id, string $item_guid) {
219
		$acl = $this->sharingACL->getItemACL($user_id, $item_guid);
220
		if (!$acl->hasPermission(SharingACL::READ | SharingACL::HISTORY)) return [];
221
222
		return $this->revisions->getRevisions($acl->getItemId());
223
	}
224
225
226
	/**
227
	 * Deletes a share request by the item ID
228
	 *
229
	 * @param ShareRequest $request
230
	 * @return int|IResult
231
	 * @throws Exception
232
	 */
233
	public function cleanItemRequestsForUser(ShareRequest $request) {
234
		return $this->shareRequest->cleanItemRequestsForUser($request->getItemId(), $request->getTargetUserId());
235
	}
236
237
	/**
238
	 * Get an share request by id
239
	 *
240
	 * @param int $id
241
	 * @return ShareRequest
242
	 * @throws DoesNotExistException
243
	 * @throws MultipleObjectsReturnedException
244
	 */
245
	public function getShareRequestById(int $id) {
246
		return $this->shareRequest->getShareRequestById($id);
247
	}
248
249
	/**
250
	 * Get an share request by $item_guid and $target_vault_guid
251
	 *
252
	 * @param string $item_guid
253
	 * @param string $target_vault_guid
254
	 * @return ShareRequest
255
	 * @throws DoesNotExistException
256
	 * @throws MultipleObjectsReturnedException
257
	 */
258
	public function getRequestByGuid(string $item_guid, string $target_vault_guid) {
259
		return $this->shareRequest->getRequestByItemAndVaultGuid($item_guid, $target_vault_guid);
260
	}
261
262
	/**
263
	 * Get the access control list by item guid
264
	 *
265
	 * @param string $item_guid
266
	 * @return SharingACL[]
267
	 */
268
	public function getCredentialAclList(string $item_guid) {
269
		return $this->sharingACL->getCredentialAclList($item_guid);
270
	}
271
272
	/**
273
	 * @param string $item_guid
274
	 * @return ShareRequest[]
275
	 * @throws Exception
276
	 */
277
	public function getCredentialPendingAclList(string $item_guid) {
278
		return $this->shareRequest->getRequestsByItemGuidGroupedByUser($item_guid);
279
	}
280
281
	/**
282
	 * Gets the ACL on the credential for the user
283
	 *
284
	 * @param string $user_id
285
	 * @param string $item_guid
286
	 * @return SharingACL
287
	 * @throws DoesNotExistException
288
	 * @throws MultipleObjectsReturnedException
289
	 */
290
	public function getCredentialAclForUser(string $user_id, string $item_guid) {
291
		return $this->sharingACL->getItemACL($user_id, $item_guid);
292
	}
293
294
	/**
295
	 * Get pending share requests by guid
296
	 *
297
	 * @param string $item_guid
298
	 * @return ShareRequest[]
299
	 */
300
	public function getShareRequestsByGuid(string $item_guid) {
301
		return $this->shareRequest->getShareRequestsByItemGuid($item_guid);
302
	}
303
304
	/**
305
	 * Get pending share requests by guid
306
	 *
307
	 * @param ShareRequest $request
308
	 * @return ShareRequest
309
	 */
310
	public function deleteShareRequest(ShareRequest $request) {
311
		return $this->shareRequest->deleteShareRequest($request);
312
	}
313
314
	/**
315
	 * Delete ACL
316
	 *
317
	 * @param SharingACL $ACL
318
	 * @return SharingACL|Entity
319
	 */
320
	public function deleteShareACL(SharingACL $ACL) {
321
		return $this->sharingACL->deleteShareACL($ACL);
322
	}
323
324
	/**
325
	 * Updates the given ACL entry
326
	 *
327
	 * @param SharingACL $sharingACL
328
	 * @return SharingACL
329
	 */
330
	public function updateCredentialACL(SharingACL $sharingACL) {
331
		return $this->sharingACL->updateCredentialACL($sharingACL);
332
	}
333
334
	/**
335
	 * @param ShareRequest $shareRequest
336
	 * @return ShareRequest
337
	 */
338
	public function updateCredentialShareRequest(ShareRequest $shareRequest) {
339
		return $this->shareRequest->updateShareRequest($shareRequest);
340
	}
341
342
343
	/**
344
	 * Get pending share requests by guid and uid
345
	 *
346
	 * @param string $item_guid
347
	 * @param string $user_id
348
	 * @return ShareRequest[]
349
	 */
350
	public function getPendingShareRequestsForCredential(string $item_guid, string $user_id) {
351
		return $this->shareRequest->getPendingShareRequests($item_guid, $user_id);
352
	}
353
354
	/**
355
	 * @param string $item_guid
356
	 * @param string $user_id
357
	 * @param int $permissions
358
	 * @return int|IResult
359
	 * @throws Exception
360
	 */
361
	public function updatePendingShareRequestsForCredential(string $item_guid, string $user_id, int $permissions) {
362
		return $this->shareRequest->updatePendingRequestPermissions($item_guid, $user_id, $permissions);
363
	}
364
365
	/**
366
	 * Clean up on credential destroyed.
367
	 * This will delete all ACL's and share requests.
368
	 * @param string $item_guid
369
	 */
370
	public function unshareCredential(string $item_guid) {
371
		$acl_list = $this->getCredentialAclList($item_guid);
372
		$request_list = $this->getShareRequestsByGuid($item_guid);
373
		foreach ($acl_list as $ACL) {
374
			$this->deleteShareACL($ACL);
375
		}
376
		foreach ($request_list as $request) {
377
			$this->deleteShareRequest($request);
378
			$notification = $this->IManager->createNotification();
379
			$notification->setApp('passman')
380
				->setObject('passman_share_request', $request->getId())
381
				->setUser($request->getTargetUserId());
382
			$this->IManager->markProcessed($notification);
383
		}
384
	}
385
}
386