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