1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc. |
4
|
|
|
* |
5
|
|
|
* @author Bjoern Schiessle <[email protected]> |
6
|
|
|
* @author Björn Schießle <[email protected]> |
7
|
|
|
* @author Robin Appelman <[email protected]> |
8
|
|
|
* @author Roeland Jago Douma <[email protected]> |
9
|
|
|
* @author Thomas Müller <[email protected]> |
10
|
|
|
* |
11
|
|
|
* @license AGPL-3.0 |
12
|
|
|
* |
13
|
|
|
* This code is free software: you can redistribute it and/or modify |
14
|
|
|
* it under the terms of the GNU Affero General Public License, version 3, |
15
|
|
|
* as published by the Free Software Foundation. |
16
|
|
|
* |
17
|
|
|
* This program is distributed in the hope that it will be useful, |
18
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
19
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20
|
|
|
* GNU Affero General Public License for more details. |
21
|
|
|
* |
22
|
|
|
* You should have received a copy of the GNU Affero General Public License, version 3, |
23
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
24
|
|
|
* |
25
|
|
|
*/ |
26
|
|
|
|
27
|
|
|
namespace OCA\FederatedFileSharing; |
28
|
|
|
|
29
|
|
|
use OC\Share20\Share; |
30
|
|
|
use OCP\Federation\ICloudIdManager; |
31
|
|
|
use OCP\DB\QueryBuilder\IQueryBuilder; |
32
|
|
|
use OCP\Files\Folder; |
33
|
|
|
use OCP\Files\IRootFolder; |
34
|
|
|
use OCP\IConfig; |
35
|
|
|
use OCP\IL10N; |
36
|
|
|
use OCP\ILogger; |
37
|
|
|
use OCP\IUserManager; |
38
|
|
|
use OCP\Share\IShare; |
39
|
|
|
use OCP\Share\IShareProvider; |
40
|
|
|
use OC\Share20\Exception\InvalidShare; |
41
|
|
|
use OCP\Share\Exceptions\ShareNotFound; |
42
|
|
|
use OCP\Files\NotFoundException; |
43
|
|
|
use OCP\IDBConnection; |
44
|
|
|
use OCP\Files\Node; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Class FederatedShareProvider |
48
|
|
|
* |
49
|
|
|
* @package OCA\FederatedFileSharing |
50
|
|
|
*/ |
51
|
|
|
class FederatedShareProvider implements IShareProvider { |
52
|
|
|
|
53
|
|
|
const SHARE_TYPE_REMOTE = 6; |
54
|
|
|
|
55
|
|
|
/** @var IDBConnection */ |
56
|
|
|
private $dbConnection; |
57
|
|
|
|
58
|
|
|
/** @var AddressHandler */ |
59
|
|
|
private $addressHandler; |
60
|
|
|
|
61
|
|
|
/** @var Notifications */ |
62
|
|
|
private $notifications; |
63
|
|
|
|
64
|
|
|
/** @var TokenHandler */ |
65
|
|
|
private $tokenHandler; |
66
|
|
|
|
67
|
|
|
/** @var IL10N */ |
68
|
|
|
private $l; |
69
|
|
|
|
70
|
|
|
/** @var ILogger */ |
71
|
|
|
private $logger; |
72
|
|
|
|
73
|
|
|
/** @var IRootFolder */ |
74
|
|
|
private $rootFolder; |
75
|
|
|
|
76
|
|
|
/** @var IConfig */ |
77
|
|
|
private $config; |
78
|
|
|
|
79
|
|
|
/** @var string */ |
80
|
|
|
private $externalShareTable = 'share_external'; |
81
|
|
|
|
82
|
|
|
/** @var IUserManager */ |
83
|
|
|
private $userManager; |
84
|
|
|
|
85
|
|
|
/** @var ICloudIdManager */ |
86
|
|
|
private $cloudIdManager; |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* DefaultShareProvider constructor. |
90
|
|
|
* |
91
|
|
|
* @param IDBConnection $connection |
92
|
|
|
* @param AddressHandler $addressHandler |
93
|
|
|
* @param Notifications $notifications |
94
|
|
|
* @param TokenHandler $tokenHandler |
95
|
|
|
* @param IL10N $l10n |
96
|
|
|
* @param ILogger $logger |
97
|
|
|
* @param IRootFolder $rootFolder |
98
|
|
|
* @param IConfig $config |
99
|
|
|
* @param IUserManager $userManager |
100
|
|
|
* @param ICloudIdManager $cloudIdManager |
101
|
|
|
*/ |
102
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
103
|
|
|
IDBConnection $connection, |
104
|
|
|
AddressHandler $addressHandler, |
105
|
|
|
Notifications $notifications, |
106
|
|
|
TokenHandler $tokenHandler, |
107
|
|
|
IL10N $l10n, |
108
|
|
|
ILogger $logger, |
109
|
|
|
IRootFolder $rootFolder, |
110
|
|
|
IConfig $config, |
111
|
|
|
IUserManager $userManager, |
112
|
|
|
ICloudIdManager $cloudIdManager |
113
|
|
|
) { |
114
|
|
|
$this->dbConnection = $connection; |
115
|
|
|
$this->addressHandler = $addressHandler; |
116
|
|
|
$this->notifications = $notifications; |
117
|
|
|
$this->tokenHandler = $tokenHandler; |
118
|
|
|
$this->l = $l10n; |
119
|
|
|
$this->logger = $logger; |
120
|
|
|
$this->rootFolder = $rootFolder; |
121
|
|
|
$this->config = $config; |
122
|
|
|
$this->userManager = $userManager; |
123
|
|
|
$this->cloudIdManager = $cloudIdManager; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Return the identifier of this provider. |
128
|
|
|
* |
129
|
|
|
* @return string Containing only [a-zA-Z0-9] |
130
|
|
|
*/ |
131
|
|
|
public function identifier() { |
132
|
|
|
return 'ocFederatedSharing'; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Share a path |
137
|
|
|
* |
138
|
|
|
* @param IShare $share |
139
|
|
|
* @return IShare The share object |
140
|
|
|
* @throws ShareNotFound |
141
|
|
|
* @throws \Exception |
142
|
|
|
*/ |
143
|
|
|
public function create(IShare $share) { |
144
|
|
|
|
145
|
|
|
$shareWith = $share->getSharedWith(); |
146
|
|
|
$itemSource = $share->getNodeId(); |
147
|
|
|
$itemType = $share->getNodeType(); |
148
|
|
|
$permissions = $share->getPermissions(); |
149
|
|
|
$sharedBy = $share->getSharedBy(); |
150
|
|
|
|
151
|
|
|
/* |
152
|
|
|
* Check if file is not already shared with the remote user |
153
|
|
|
*/ |
154
|
|
|
$alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0); |
155
|
|
View Code Duplication |
if (!empty($alreadyShared)) { |
156
|
|
|
$message = 'Sharing %s failed, because this item is already shared with %s'; |
157
|
|
|
$message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith)); |
158
|
|
|
$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']); |
159
|
|
|
throw new \Exception($message_t); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
|
163
|
|
|
// don't allow federated shares if source and target server are the same |
164
|
|
|
$cloudId = $this->cloudIdManager->resolveCloudId($shareWith); |
165
|
|
|
$currentServer = $this->addressHandler->generateRemoteURL(); |
166
|
|
|
$currentUser = $sharedBy; |
167
|
|
|
if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) { |
168
|
|
|
$message = 'Not allowed to create a federated share with the same user.'; |
169
|
|
|
$message_t = $this->l->t('Not allowed to create a federated share with the same user'); |
170
|
|
|
$this->logger->debug($message, ['app' => 'Federated File Sharing']); |
171
|
|
|
throw new \Exception($message_t); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
|
175
|
|
|
$share->setSharedWith($cloudId->getId()); |
176
|
|
|
|
177
|
|
|
try { |
178
|
|
|
$remoteShare = $this->getShareFromExternalShareTable($share); |
179
|
|
|
} catch (ShareNotFound $e) { |
180
|
|
|
$remoteShare = null; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
if ($remoteShare) { |
184
|
|
|
try { |
185
|
|
|
$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']); |
186
|
|
|
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time()); |
187
|
|
|
$share->setId($shareId); |
188
|
|
|
list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId); |
189
|
|
|
// remote share was create successfully if we get a valid token as return |
190
|
|
|
$send = is_string($token) && $token !== ''; |
191
|
|
|
} catch (\Exception $e) { |
192
|
|
|
// fall back to old re-share behavior if the remote server |
193
|
|
|
// doesn't support flat re-shares (was introduced with Nextcloud 9.1) |
194
|
|
|
$this->removeShareFromTable($share); |
195
|
|
|
$shareId = $this->createFederatedShare($share); |
196
|
|
|
} |
197
|
|
|
if ($send) { |
|
|
|
|
198
|
|
|
$this->updateSuccessfulReshare($shareId, $token); |
|
|
|
|
199
|
|
|
$this->storeRemoteId($shareId, $remoteId); |
|
|
|
|
200
|
|
|
} else { |
201
|
|
|
$this->removeShareFromTable($share); |
202
|
|
|
$message_t = $this->l->t('File is already shared with %s', [$shareWith]); |
203
|
|
|
throw new \Exception($message_t); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
} else { |
207
|
|
|
$shareId = $this->createFederatedShare($share); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
$data = $this->getRawShare($shareId); |
211
|
|
|
return $this->createShareObject($data); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* create federated share and inform the recipient |
216
|
|
|
* |
217
|
|
|
* @param IShare $share |
218
|
|
|
* @return int |
219
|
|
|
* @throws ShareNotFound |
220
|
|
|
* @throws \Exception |
221
|
|
|
*/ |
222
|
|
|
protected function createFederatedShare(IShare $share) { |
223
|
|
|
$token = $this->tokenHandler->generateToken(); |
224
|
|
|
$shareId = $this->addShareToDB( |
225
|
|
|
$share->getNodeId(), |
226
|
|
|
$share->getNodeType(), |
227
|
|
|
$share->getSharedWith(), |
228
|
|
|
$share->getSharedBy(), |
229
|
|
|
$share->getShareOwner(), |
230
|
|
|
$share->getPermissions(), |
231
|
|
|
$token |
232
|
|
|
); |
233
|
|
|
|
234
|
|
|
$failure = false; |
235
|
|
|
|
236
|
|
|
try { |
237
|
|
|
$sharedByFederatedId = $share->getSharedBy(); |
238
|
|
|
if ($this->userManager->userExists($sharedByFederatedId)) { |
239
|
|
|
$cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL()); |
240
|
|
|
$sharedByFederatedId = $cloudId->getId(); |
241
|
|
|
} |
242
|
|
|
$ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL()); |
243
|
|
|
$send = $this->notifications->sendRemoteShare( |
244
|
|
|
$token, |
245
|
|
|
$share->getSharedWith(), |
246
|
|
|
$share->getNode()->getName(), |
247
|
|
|
$shareId, |
248
|
|
|
$share->getShareOwner(), |
249
|
|
|
$ownerCloudId->getId(), |
250
|
|
|
$share->getSharedBy(), |
251
|
|
|
$sharedByFederatedId |
252
|
|
|
); |
253
|
|
|
|
254
|
|
|
if ($send === false) { |
255
|
|
|
$failure = true; |
256
|
|
|
} |
257
|
|
|
} catch (\Exception $e) { |
258
|
|
|
$this->logger->error('Failed to notify remote server of federated share, removing share (' . $e->getMessage() . ')'); |
259
|
|
|
$failure = true; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
if($failure) { |
263
|
|
|
$this->removeShareFromTableById($shareId); |
264
|
|
|
$message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate.', |
265
|
|
|
[$share->getNode()->getName(), $share->getSharedWith()]); |
266
|
|
|
throw new \Exception($message_t); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
return $shareId; |
270
|
|
|
|
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* @param string $shareWith |
275
|
|
|
* @param IShare $share |
276
|
|
|
* @param string $shareId internal share Id |
277
|
|
|
* @return array |
278
|
|
|
* @throws \Exception |
279
|
|
|
*/ |
280
|
|
|
protected function askOwnerToReShare($shareWith, IShare $share, $shareId) { |
281
|
|
|
|
282
|
|
|
$remoteShare = $this->getShareFromExternalShareTable($share); |
283
|
|
|
$token = $remoteShare['share_token']; |
284
|
|
|
$remoteId = $remoteShare['remote_id']; |
285
|
|
|
$remote = $remoteShare['remote']; |
286
|
|
|
|
287
|
|
|
list($token, $remoteId) = $this->notifications->requestReShare( |
288
|
|
|
$token, |
289
|
|
|
$remoteId, |
290
|
|
|
$shareId, |
291
|
|
|
$remote, |
292
|
|
|
$shareWith, |
293
|
|
|
$share->getPermissions() |
294
|
|
|
); |
295
|
|
|
|
296
|
|
|
return [$token, $remoteId]; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* get federated share from the share_external table but exclude mounted link shares |
301
|
|
|
* |
302
|
|
|
* @param IShare $share |
303
|
|
|
* @return array |
304
|
|
|
* @throws ShareNotFound |
305
|
|
|
*/ |
306
|
|
|
protected function getShareFromExternalShareTable(IShare $share) { |
307
|
|
|
$query = $this->dbConnection->getQueryBuilder(); |
308
|
|
|
$query->select('*')->from($this->externalShareTable) |
309
|
|
|
->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner()))) |
310
|
|
|
->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget()))); |
311
|
|
|
$result = $query->execute()->fetchAll(); |
312
|
|
|
|
313
|
|
|
if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) { |
314
|
|
|
return $result[0]; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
throw new ShareNotFound('share not found in share_external table'); |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* add share to the database and return the ID |
322
|
|
|
* |
323
|
|
|
* @param int $itemSource |
324
|
|
|
* @param string $itemType |
325
|
|
|
* @param string $shareWith |
326
|
|
|
* @param string $sharedBy |
327
|
|
|
* @param string $uidOwner |
328
|
|
|
* @param int $permissions |
329
|
|
|
* @param string $token |
330
|
|
|
* @return int |
331
|
|
|
*/ |
332
|
|
View Code Duplication |
private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) { |
|
|
|
|
333
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
334
|
|
|
$qb->insert('share') |
335
|
|
|
->setValue('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)) |
336
|
|
|
->setValue('item_type', $qb->createNamedParameter($itemType)) |
337
|
|
|
->setValue('item_source', $qb->createNamedParameter($itemSource)) |
338
|
|
|
->setValue('file_source', $qb->createNamedParameter($itemSource)) |
339
|
|
|
->setValue('share_with', $qb->createNamedParameter($shareWith)) |
340
|
|
|
->setValue('uid_owner', $qb->createNamedParameter($uidOwner)) |
341
|
|
|
->setValue('uid_initiator', $qb->createNamedParameter($sharedBy)) |
342
|
|
|
->setValue('permissions', $qb->createNamedParameter($permissions)) |
343
|
|
|
->setValue('token', $qb->createNamedParameter($token)) |
344
|
|
|
->setValue('stime', $qb->createNamedParameter(time())); |
345
|
|
|
|
346
|
|
|
/* |
347
|
|
|
* Added to fix https://github.com/owncloud/core/issues/22215 |
348
|
|
|
* Can be removed once we get rid of ajax/share.php |
349
|
|
|
*/ |
350
|
|
|
$qb->setValue('file_target', $qb->createNamedParameter('')); |
351
|
|
|
|
352
|
|
|
$qb->execute(); |
353
|
|
|
$id = $qb->getLastInsertId(); |
354
|
|
|
|
355
|
|
|
return (int)$id; |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* Update a share |
360
|
|
|
* |
361
|
|
|
* @param IShare $share |
362
|
|
|
* @return IShare The share object |
363
|
|
|
*/ |
364
|
|
|
public function update(IShare $share) { |
365
|
|
|
/* |
366
|
|
|
* We allow updating the permissions of federated shares |
367
|
|
|
*/ |
368
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
369
|
|
|
$qb->update('share') |
370
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) |
371
|
|
|
->set('permissions', $qb->createNamedParameter($share->getPermissions())) |
372
|
|
|
->set('uid_owner', $qb->createNamedParameter($share->getShareOwner())) |
373
|
|
|
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy())) |
374
|
|
|
->execute(); |
375
|
|
|
|
376
|
|
|
// send the updated permission to the owner/initiator, if they are not the same |
377
|
|
|
if ($share->getShareOwner() !== $share->getSharedBy()) { |
378
|
|
|
$this->sendPermissionUpdate($share); |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
return $share; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* send the updated permission to the owner/initiator, if they are not the same |
386
|
|
|
* |
387
|
|
|
* @param IShare $share |
388
|
|
|
* @throws ShareNotFound |
389
|
|
|
* @throws \OC\HintException |
390
|
|
|
*/ |
391
|
|
View Code Duplication |
protected function sendPermissionUpdate(IShare $share) { |
|
|
|
|
392
|
|
|
$remoteId = $this->getRemoteId($share); |
393
|
|
|
// if the local user is the owner we send the permission change to the initiator |
394
|
|
|
if ($this->userManager->userExists($share->getShareOwner())) { |
395
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy()); |
396
|
|
|
} else { // ... if not we send the permission change to the owner |
397
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner()); |
398
|
|
|
} |
399
|
|
|
$this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions()); |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
|
403
|
|
|
/** |
404
|
|
|
* update successful reShare with the correct token |
405
|
|
|
* |
406
|
|
|
* @param int $shareId |
407
|
|
|
* @param string $token |
408
|
|
|
*/ |
409
|
|
View Code Duplication |
protected function updateSuccessfulReShare($shareId, $token) { |
|
|
|
|
410
|
|
|
$query = $this->dbConnection->getQueryBuilder(); |
411
|
|
|
$query->update('share') |
412
|
|
|
->where($query->expr()->eq('id', $query->createNamedParameter($shareId))) |
413
|
|
|
->set('token', $query->createNamedParameter($token)) |
414
|
|
|
->execute(); |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* store remote ID in federated reShare table |
419
|
|
|
* |
420
|
|
|
* @param $shareId |
421
|
|
|
* @param $remoteId |
422
|
|
|
*/ |
423
|
|
|
public function storeRemoteId($shareId, $remoteId) { |
424
|
|
|
$query = $this->dbConnection->getQueryBuilder(); |
425
|
|
|
$query->insert('federated_reshares') |
426
|
|
|
->values( |
427
|
|
|
[ |
428
|
|
|
'share_id' => $query->createNamedParameter($shareId), |
429
|
|
|
'remote_id' => $query->createNamedParameter($remoteId), |
430
|
|
|
] |
431
|
|
|
); |
432
|
|
|
$query->execute(); |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
/** |
436
|
|
|
* get share ID on remote server for federated re-shares |
437
|
|
|
* |
438
|
|
|
* @param IShare $share |
439
|
|
|
* @return int |
440
|
|
|
* @throws ShareNotFound |
441
|
|
|
*/ |
442
|
|
|
public function getRemoteId(IShare $share) { |
443
|
|
|
$query = $this->dbConnection->getQueryBuilder(); |
444
|
|
|
$query->select('remote_id')->from('federated_reshares') |
445
|
|
|
->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId()))); |
446
|
|
|
$data = $query->execute()->fetch(); |
447
|
|
|
|
448
|
|
|
if (!is_array($data) || !isset($data['remote_id'])) { |
449
|
|
|
throw new ShareNotFound(); |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
return (int)$data['remote_id']; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* @inheritdoc |
457
|
|
|
*/ |
458
|
|
|
public function move(IShare $share, $recipient) { |
459
|
|
|
/* |
460
|
|
|
* This function does nothing yet as it is just for outgoing |
461
|
|
|
* federated shares. |
462
|
|
|
*/ |
463
|
|
|
return $share; |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* Get all children of this share |
468
|
|
|
* |
469
|
|
|
* @param IShare $parent |
470
|
|
|
* @return IShare[] |
471
|
|
|
*/ |
472
|
|
View Code Duplication |
public function getChildren(IShare $parent) { |
|
|
|
|
473
|
|
|
$children = []; |
474
|
|
|
|
475
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
476
|
|
|
$qb->select('*') |
477
|
|
|
->from('share') |
478
|
|
|
->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId()))) |
479
|
|
|
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))) |
480
|
|
|
->orderBy('id'); |
481
|
|
|
|
482
|
|
|
$cursor = $qb->execute(); |
483
|
|
|
while($data = $cursor->fetch()) { |
484
|
|
|
$children[] = $this->createShareObject($data); |
485
|
|
|
} |
486
|
|
|
$cursor->closeCursor(); |
487
|
|
|
|
488
|
|
|
return $children; |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
/** |
492
|
|
|
* Delete a share (owner unShares the file) |
493
|
|
|
* |
494
|
|
|
* @param IShare $share |
495
|
|
|
*/ |
496
|
|
|
public function delete(IShare $share) { |
497
|
|
|
|
498
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith()); |
499
|
|
|
|
500
|
|
|
$isOwner = false; |
501
|
|
|
|
502
|
|
|
$this->removeShareFromTable($share); |
503
|
|
|
|
504
|
|
|
// if the local user is the owner we can send the unShare request directly... |
505
|
|
|
if ($this->userManager->userExists($share->getShareOwner())) { |
506
|
|
|
$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken()); |
507
|
|
|
$this->revokeShare($share, true); |
508
|
|
|
$isOwner = true; |
509
|
|
|
} else { // ... if not we need to correct ID for the unShare request |
510
|
|
|
$remoteId = $this->getRemoteId($share); |
511
|
|
|
$this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken()); |
512
|
|
|
$this->revokeShare($share, false); |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
// send revoke notification to the other user, if initiator and owner are not the same user |
516
|
|
|
if ($share->getShareOwner() !== $share->getSharedBy()) { |
517
|
|
|
$remoteId = $this->getRemoteId($share); |
518
|
|
|
if ($isOwner) { |
519
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy()); |
520
|
|
|
} else { |
521
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner()); |
522
|
|
|
} |
523
|
|
|
$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken()); |
524
|
|
|
} |
525
|
|
|
} |
526
|
|
|
|
527
|
|
|
/** |
528
|
|
|
* in case of a re-share we need to send the other use (initiator or owner) |
529
|
|
|
* a message that the file was unshared |
530
|
|
|
* |
531
|
|
|
* @param IShare $share |
532
|
|
|
* @param bool $isOwner the user can either be the owner or the user who re-sahred it |
533
|
|
|
* @throws ShareNotFound |
534
|
|
|
* @throws \OC\HintException |
535
|
|
|
*/ |
536
|
|
View Code Duplication |
protected function revokeShare($share, $isOwner) { |
|
|
|
|
537
|
|
|
// also send a unShare request to the initiator, if this is a different user than the owner |
538
|
|
|
if ($share->getShareOwner() !== $share->getSharedBy()) { |
539
|
|
|
if ($isOwner) { |
540
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy()); |
541
|
|
|
} else { |
542
|
|
|
list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner()); |
543
|
|
|
} |
544
|
|
|
$remoteId = $this->getRemoteId($share); |
545
|
|
|
$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken()); |
546
|
|
|
} |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
/** |
550
|
|
|
* remove share from table |
551
|
|
|
* |
552
|
|
|
* @param IShare $share |
553
|
|
|
*/ |
554
|
|
|
public function removeShareFromTable(IShare $share) { |
555
|
|
|
$this->removeShareFromTableById($share->getId()); |
556
|
|
|
} |
557
|
|
|
|
558
|
|
|
/** |
559
|
|
|
* remove share from table |
560
|
|
|
* |
561
|
|
|
* @param string $shareId |
562
|
|
|
*/ |
563
|
|
|
private function removeShareFromTableById($shareId) { |
564
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
565
|
|
|
$qb->delete('share') |
566
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId))); |
567
|
|
|
$qb->execute(); |
568
|
|
|
|
569
|
|
|
$qb->delete('federated_reshares') |
570
|
|
|
->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId))); |
571
|
|
|
$qb->execute(); |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
/** |
575
|
|
|
* @inheritdoc |
576
|
|
|
*/ |
577
|
|
|
public function deleteFromSelf(IShare $share, $recipient) { |
578
|
|
|
// nothing to do here. Technically deleteFromSelf in the context of federated |
579
|
|
|
// shares is a umount of a external storage. This is handled here |
580
|
|
|
// apps/files_sharing/lib/external/manager.php |
581
|
|
|
// TODO move this code over to this app |
582
|
|
|
return; |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
|
586
|
|
View Code Duplication |
public function getSharesInFolder($userId, Folder $node, $reshares) { |
|
|
|
|
587
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
588
|
|
|
$qb->select('*') |
589
|
|
|
->from('share', 's') |
590
|
|
|
->andWhere($qb->expr()->orX( |
591
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')), |
592
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) |
593
|
|
|
)) |
594
|
|
|
->andWhere( |
595
|
|
|
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)) |
596
|
|
|
); |
597
|
|
|
|
598
|
|
|
/** |
599
|
|
|
* Reshares for this user are shares where they are the owner. |
600
|
|
|
*/ |
601
|
|
|
if ($reshares === false) { |
602
|
|
|
$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); |
603
|
|
|
} else { |
604
|
|
|
$qb->andWhere( |
605
|
|
|
$qb->expr()->orX( |
606
|
|
|
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
607
|
|
|
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) |
608
|
|
|
) |
609
|
|
|
); |
610
|
|
|
} |
611
|
|
|
|
612
|
|
|
$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid')); |
613
|
|
|
$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId()))); |
614
|
|
|
|
615
|
|
|
$qb->orderBy('id'); |
616
|
|
|
|
617
|
|
|
$cursor = $qb->execute(); |
618
|
|
|
$shares = []; |
619
|
|
|
while ($data = $cursor->fetch()) { |
620
|
|
|
$shares[$data['fileid']][] = $this->createShareObject($data); |
621
|
|
|
} |
622
|
|
|
$cursor->closeCursor(); |
623
|
|
|
|
624
|
|
|
return $shares; |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
/** |
628
|
|
|
* @inheritdoc |
629
|
|
|
*/ |
630
|
|
View Code Duplication |
public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) { |
|
|
|
|
631
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
632
|
|
|
$qb->select('*') |
633
|
|
|
->from('share'); |
634
|
|
|
|
635
|
|
|
$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))); |
636
|
|
|
|
637
|
|
|
/** |
638
|
|
|
* Reshares for this user are shares where they are the owner. |
639
|
|
|
*/ |
640
|
|
|
if ($reshares === false) { |
641
|
|
|
//Special case for old shares created via the web UI |
642
|
|
|
$or1 = $qb->expr()->andX( |
643
|
|
|
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
644
|
|
|
$qb->expr()->isNull('uid_initiator') |
645
|
|
|
); |
646
|
|
|
|
647
|
|
|
$qb->andWhere( |
648
|
|
|
$qb->expr()->orX( |
649
|
|
|
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)), |
650
|
|
|
$or1 |
651
|
|
|
) |
652
|
|
|
); |
653
|
|
|
} else { |
654
|
|
|
$qb->andWhere( |
655
|
|
|
$qb->expr()->orX( |
656
|
|
|
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
657
|
|
|
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) |
658
|
|
|
) |
659
|
|
|
); |
660
|
|
|
} |
661
|
|
|
|
662
|
|
|
if ($node !== null) { |
663
|
|
|
$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); |
664
|
|
|
} |
665
|
|
|
|
666
|
|
|
if ($limit !== -1) { |
667
|
|
|
$qb->setMaxResults($limit); |
668
|
|
|
} |
669
|
|
|
|
670
|
|
|
$qb->setFirstResult($offset); |
671
|
|
|
$qb->orderBy('id'); |
672
|
|
|
|
673
|
|
|
$cursor = $qb->execute(); |
674
|
|
|
$shares = []; |
675
|
|
|
while($data = $cursor->fetch()) { |
676
|
|
|
$shares[] = $this->createShareObject($data); |
677
|
|
|
} |
678
|
|
|
$cursor->closeCursor(); |
679
|
|
|
|
680
|
|
|
return $shares; |
681
|
|
|
} |
682
|
|
|
|
683
|
|
|
/** |
684
|
|
|
* @inheritdoc |
685
|
|
|
*/ |
686
|
|
View Code Duplication |
public function getShareById($id, $recipientId = null) { |
|
|
|
|
687
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
688
|
|
|
|
689
|
|
|
$qb->select('*') |
690
|
|
|
->from('share') |
691
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) |
692
|
|
|
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))); |
693
|
|
|
|
694
|
|
|
$cursor = $qb->execute(); |
695
|
|
|
$data = $cursor->fetch(); |
696
|
|
|
$cursor->closeCursor(); |
697
|
|
|
|
698
|
|
|
if ($data === false) { |
699
|
|
|
throw new ShareNotFound(); |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
try { |
703
|
|
|
$share = $this->createShareObject($data); |
704
|
|
|
} catch (InvalidShare $e) { |
705
|
|
|
throw new ShareNotFound(); |
706
|
|
|
} |
707
|
|
|
|
708
|
|
|
return $share; |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
/** |
712
|
|
|
* Get shares for a given path |
713
|
|
|
* |
714
|
|
|
* @param \OCP\Files\Node $path |
715
|
|
|
* @return IShare[] |
716
|
|
|
*/ |
717
|
|
View Code Duplication |
public function getSharesByPath(Node $path) { |
|
|
|
|
718
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
719
|
|
|
|
720
|
|
|
$cursor = $qb->select('*') |
721
|
|
|
->from('share') |
722
|
|
|
->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId()))) |
723
|
|
|
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))) |
724
|
|
|
->execute(); |
725
|
|
|
|
726
|
|
|
$shares = []; |
727
|
|
|
while($data = $cursor->fetch()) { |
728
|
|
|
$shares[] = $this->createShareObject($data); |
729
|
|
|
} |
730
|
|
|
$cursor->closeCursor(); |
731
|
|
|
|
732
|
|
|
return $shares; |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
/** |
736
|
|
|
* @inheritdoc |
737
|
|
|
*/ |
738
|
|
View Code Duplication |
public function getSharedWith($userId, $shareType, $node, $limit, $offset) { |
|
|
|
|
739
|
|
|
/** @var IShare[] $shares */ |
740
|
|
|
$shares = []; |
741
|
|
|
|
742
|
|
|
//Get shares directly with this user |
743
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
744
|
|
|
$qb->select('*') |
745
|
|
|
->from('share'); |
746
|
|
|
|
747
|
|
|
// Order by id |
748
|
|
|
$qb->orderBy('id'); |
749
|
|
|
|
750
|
|
|
// Set limit and offset |
751
|
|
|
if ($limit !== -1) { |
752
|
|
|
$qb->setMaxResults($limit); |
753
|
|
|
} |
754
|
|
|
$qb->setFirstResult($offset); |
755
|
|
|
|
756
|
|
|
$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))); |
757
|
|
|
$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId))); |
758
|
|
|
|
759
|
|
|
// Filter by node if provided |
760
|
|
|
if ($node !== null) { |
761
|
|
|
$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); |
762
|
|
|
} |
763
|
|
|
|
764
|
|
|
$cursor = $qb->execute(); |
765
|
|
|
|
766
|
|
|
while($data = $cursor->fetch()) { |
767
|
|
|
$shares[] = $this->createShareObject($data); |
768
|
|
|
} |
769
|
|
|
$cursor->closeCursor(); |
770
|
|
|
|
771
|
|
|
|
772
|
|
|
return $shares; |
773
|
|
|
} |
774
|
|
|
|
775
|
|
|
/** |
776
|
|
|
* Get a share by token |
777
|
|
|
* |
778
|
|
|
* @param string $token |
779
|
|
|
* @return IShare |
780
|
|
|
* @throws ShareNotFound |
781
|
|
|
*/ |
782
|
|
View Code Duplication |
public function getShareByToken($token) { |
|
|
|
|
783
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
784
|
|
|
|
785
|
|
|
$cursor = $qb->select('*') |
786
|
|
|
->from('share') |
787
|
|
|
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))) |
788
|
|
|
->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token))) |
789
|
|
|
->execute(); |
790
|
|
|
|
791
|
|
|
$data = $cursor->fetch(); |
792
|
|
|
|
793
|
|
|
if ($data === false) { |
794
|
|
|
throw new ShareNotFound('Share not found', $this->l->t('Could not find share')); |
795
|
|
|
} |
796
|
|
|
|
797
|
|
|
try { |
798
|
|
|
$share = $this->createShareObject($data); |
799
|
|
|
} catch (InvalidShare $e) { |
800
|
|
|
throw new ShareNotFound('Share not found', $this->l->t('Could not find share')); |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
return $share; |
804
|
|
|
} |
805
|
|
|
|
806
|
|
|
/** |
807
|
|
|
* get database row of a give share |
808
|
|
|
* |
809
|
|
|
* @param $id |
810
|
|
|
* @return array |
811
|
|
|
* @throws ShareNotFound |
812
|
|
|
*/ |
813
|
|
View Code Duplication |
private function getRawShare($id) { |
|
|
|
|
814
|
|
|
|
815
|
|
|
// Now fetch the inserted share and create a complete share object |
816
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
817
|
|
|
$qb->select('*') |
818
|
|
|
->from('share') |
819
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); |
820
|
|
|
|
821
|
|
|
$cursor = $qb->execute(); |
822
|
|
|
$data = $cursor->fetch(); |
823
|
|
|
$cursor->closeCursor(); |
824
|
|
|
|
825
|
|
|
if ($data === false) { |
826
|
|
|
throw new ShareNotFound; |
827
|
|
|
} |
828
|
|
|
|
829
|
|
|
return $data; |
830
|
|
|
} |
831
|
|
|
|
832
|
|
|
/** |
833
|
|
|
* Create a share object from an database row |
834
|
|
|
* |
835
|
|
|
* @param array $data |
836
|
|
|
* @return IShare |
837
|
|
|
* @throws InvalidShare |
838
|
|
|
* @throws ShareNotFound |
839
|
|
|
*/ |
840
|
|
|
private function createShareObject($data) { |
841
|
|
|
|
842
|
|
|
$share = new Share($this->rootFolder, $this->userManager); |
843
|
|
|
$share->setId((int)$data['id']) |
844
|
|
|
->setShareType((int)$data['share_type']) |
845
|
|
|
->setPermissions((int)$data['permissions']) |
846
|
|
|
->setTarget($data['file_target']) |
847
|
|
|
->setMailSend((bool)$data['mail_send']) |
848
|
|
|
->setToken($data['token']); |
849
|
|
|
|
850
|
|
|
$shareTime = new \DateTime(); |
851
|
|
|
$shareTime->setTimestamp((int)$data['stime']); |
852
|
|
|
$share->setShareTime($shareTime); |
853
|
|
|
$share->setSharedWith($data['share_with']); |
854
|
|
|
|
855
|
|
|
if ($data['uid_initiator'] !== null) { |
856
|
|
|
$share->setShareOwner($data['uid_owner']); |
857
|
|
|
$share->setSharedBy($data['uid_initiator']); |
858
|
|
|
} else { |
859
|
|
|
//OLD SHARE |
860
|
|
|
$share->setSharedBy($data['uid_owner']); |
861
|
|
|
$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']); |
862
|
|
|
|
863
|
|
|
$owner = $path->getOwner(); |
864
|
|
|
$share->setShareOwner($owner->getUID()); |
865
|
|
|
} |
866
|
|
|
|
867
|
|
|
$share->setNodeId((int)$data['file_source']); |
868
|
|
|
$share->setNodeType($data['item_type']); |
869
|
|
|
|
870
|
|
|
$share->setProviderId($this->identifier()); |
871
|
|
|
|
872
|
|
|
return $share; |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
/** |
876
|
|
|
* Get the node with file $id for $user |
877
|
|
|
* |
878
|
|
|
* @param string $userId |
879
|
|
|
* @param int $id |
880
|
|
|
* @return \OCP\Files\File|\OCP\Files\Folder |
881
|
|
|
* @throws InvalidShare |
882
|
|
|
*/ |
883
|
|
View Code Duplication |
private function getNode($userId, $id) { |
|
|
|
|
884
|
|
|
try { |
885
|
|
|
$userFolder = $this->rootFolder->getUserFolder($userId); |
886
|
|
|
} catch (NotFoundException $e) { |
887
|
|
|
throw new InvalidShare(); |
888
|
|
|
} |
889
|
|
|
|
890
|
|
|
$nodes = $userFolder->getById($id); |
891
|
|
|
|
892
|
|
|
if (empty($nodes)) { |
893
|
|
|
throw new InvalidShare(); |
894
|
|
|
} |
895
|
|
|
|
896
|
|
|
return $nodes[0]; |
897
|
|
|
} |
898
|
|
|
|
899
|
|
|
/** |
900
|
|
|
* A user is deleted from the system |
901
|
|
|
* So clean up the relevant shares. |
902
|
|
|
* |
903
|
|
|
* @param string $uid |
904
|
|
|
* @param int $shareType |
905
|
|
|
*/ |
906
|
|
View Code Duplication |
public function userDeleted($uid, $shareType) { |
|
|
|
|
907
|
|
|
//TODO: probabaly a good idea to send unshare info to remote servers |
908
|
|
|
|
909
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
910
|
|
|
|
911
|
|
|
$qb->delete('share') |
912
|
|
|
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))) |
913
|
|
|
->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))) |
914
|
|
|
->execute(); |
915
|
|
|
} |
916
|
|
|
|
917
|
|
|
/** |
918
|
|
|
* This provider does not handle groups |
919
|
|
|
* |
920
|
|
|
* @param string $gid |
921
|
|
|
*/ |
922
|
|
|
public function groupDeleted($gid) { |
923
|
|
|
// We don't handle groups here |
924
|
|
|
return; |
925
|
|
|
} |
926
|
|
|
|
927
|
|
|
/** |
928
|
|
|
* This provider does not handle groups |
929
|
|
|
* |
930
|
|
|
* @param string $uid |
931
|
|
|
* @param string $gid |
932
|
|
|
*/ |
933
|
|
|
public function userDeletedFromGroup($uid, $gid) { |
934
|
|
|
// We don't handle groups here |
935
|
|
|
return; |
936
|
|
|
} |
937
|
|
|
|
938
|
|
|
/** |
939
|
|
|
* check if users from other Nextcloud instances are allowed to mount public links share by this instance |
940
|
|
|
* |
941
|
|
|
* @return bool |
942
|
|
|
*/ |
943
|
|
|
public function isOutgoingServer2serverShareEnabled() { |
944
|
|
|
$result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes'); |
945
|
|
|
return ($result === 'yes'); |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
/** |
949
|
|
|
* check if users are allowed to mount public links from other Nextclouds |
950
|
|
|
* |
951
|
|
|
* @return bool |
952
|
|
|
*/ |
953
|
|
|
public function isIncomingServer2serverShareEnabled() { |
954
|
|
|
$result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes'); |
955
|
|
|
return ($result === 'yes'); |
956
|
|
|
} |
957
|
|
|
|
958
|
|
|
/** |
959
|
|
|
* Check if querying sharees on the lookup server is enabled |
960
|
|
|
* |
961
|
|
|
* @return bool |
962
|
|
|
*/ |
963
|
|
|
public function isLookupServerQueriesEnabled() { |
964
|
|
|
$result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no'); |
965
|
|
|
return ($result === 'yes'); |
966
|
|
|
} |
967
|
|
|
|
968
|
|
|
|
969
|
|
|
/** |
970
|
|
|
* Check if it is allowed to publish user specific data to the lookup server |
971
|
|
|
* |
972
|
|
|
* @return bool |
973
|
|
|
*/ |
974
|
|
|
public function isLookupServerUploadEnabled() { |
975
|
|
|
$result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes'); |
976
|
|
|
return ($result === 'yes'); |
977
|
|
|
} |
978
|
|
|
|
979
|
|
|
/** |
980
|
|
|
* @inheritdoc |
981
|
|
|
*/ |
982
|
|
|
public function getAccessList($nodes, $currentAccess) { |
983
|
|
|
$ids = []; |
984
|
|
|
foreach ($nodes as $node) { |
985
|
|
|
$ids[] = $node->getId(); |
986
|
|
|
} |
987
|
|
|
|
988
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
989
|
|
|
$qb->select('share_with', 'token', 'file_source') |
990
|
|
|
->from('share') |
991
|
|
|
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))) |
992
|
|
|
->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))) |
993
|
|
|
->andWhere($qb->expr()->orX( |
994
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')), |
995
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) |
996
|
|
|
)); |
997
|
|
|
$cursor = $qb->execute(); |
998
|
|
|
|
999
|
|
|
if ($currentAccess === false) { |
1000
|
|
|
$remote = $cursor->fetch() !== false; |
1001
|
|
|
$cursor->closeCursor(); |
1002
|
|
|
|
1003
|
|
|
return ['remote' => $remote]; |
1004
|
|
|
} |
1005
|
|
|
|
1006
|
|
|
$remote = []; |
1007
|
|
|
while ($row = $cursor->fetch()) { |
1008
|
|
|
$remote[$row['share_with']] = [ |
1009
|
|
|
'node_id' => $row['file_source'], |
1010
|
|
|
'token' => $row['token'], |
1011
|
|
|
]; |
1012
|
|
|
} |
1013
|
|
|
$cursor->closeCursor(); |
1014
|
|
|
|
1015
|
|
|
return ['remote' => $remote]; |
1016
|
|
|
} |
1017
|
|
|
} |
1018
|
|
|
|
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.