Completed
Pull Request — master (#9345)
by Björn
89:47 queued 65:13
created
apps/federatedfilesharing/lib/Notifications.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
 			$ocsStatus = isset($status['ocs']);
118 118
 			$ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
119 119
 
120
-			if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) {
120
+			if ($result['success'] && (!$ocsStatus || $ocsSuccess)) {
121 121
 				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
122 122
 				return true;
123 123
 			}
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
 			return [$ocmResult['token'], $ocmResult['providerId']];
161 161
 		}
162 162
 
163
-		$result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
163
+		$result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/'.$id.'/reshare', $fields);
164 164
 		$status = json_decode($result['result'], true);
165 165
 
166 166
 		$httpRequestSuccessful = $result['success'];
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
 		if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
172 172
 			return [
173 173
 				$status['ocs']['data']['token'],
174
-				(int)$status['ocs']['data']['remoteId']
174
+				(int) $status['ocs']['data']['remoteId']
175 175
 			];
176 176
 		}
177 177
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
 			$fields[$key] = $value;
259 259
 		}
260 260
 
261
-		$result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action);
261
+		$result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/'.$remoteId.'/'.$action, $fields, $action);
262 262
 		$status = json_decode($result['result'], true);
263 263
 
264 264
 		if ($result['success'] &&
@@ -306,10 +306,10 @@  discard block
 block discarded – undo
306 306
 	 * @return array
307 307
 	 * @throws \Exception
308 308
 	 */
309
-	protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") {
309
+	protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action = "share") {
310 310
 
311 311
 		if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
312
-			$remoteDomain = 'https://' . $remoteDomain;
312
+			$remoteDomain = 'https://'.$remoteDomain;
313 313
 		}
314 314
 
315 315
 		$result = [
@@ -348,7 +348,7 @@  discard block
 block discarded – undo
348 348
 		$federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING');
349 349
 		$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
350 350
 		try {
351
-			$response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
351
+			$response = $client->post($remoteDomain.$endpoint.$urlSuffix.'?format='.self::RESPONSE_FORMAT, [
352 352
 				'body' => $fields,
353 353
 				'timeout' => 10,
354 354
 				'connect_timeout' => 10,
@@ -405,7 +405,7 @@  discard block
 block discarded – undo
405 405
 		switch ($action) {
406 406
 			case 'share':
407 407
 				$share = $this->cloudFederationFactory->getCloudFederationShare(
408
-					$fields['shareWith'] . '@' . $remoteDomain,
408
+					$fields['shareWith'].'@'.$remoteDomain,
409 409
 					$fields['name'],
410 410
 					'',
411 411
 					$fields['remoteId'],
Please login to merge, or discard this patch.
Indentation   +430 added lines, -430 removed lines patch added patch discarded remove patch
@@ -33,434 +33,434 @@
 block discarded – undo
33 33
 use OCP\OCS\IDiscoveryService;
34 34
 
35 35
 class Notifications {
36
-	const RESPONSE_FORMAT = 'json'; // default response format for ocs calls
37
-
38
-	/** @var AddressHandler */
39
-	private $addressHandler;
40
-
41
-	/** @var IClientService */
42
-	private $httpClientService;
43
-
44
-	/** @var IDiscoveryService */
45
-	private $discoveryService;
46
-
47
-	/** @var IJobList  */
48
-	private $jobList;
49
-
50
-	/** @var ICloudFederationProviderManager */
51
-	private $federationProviderManager;
52
-
53
-	/** @var ICloudFederationFactory */
54
-	private $cloudFederationFactory;
55
-
56
-	/**
57
-	 * @param AddressHandler $addressHandler
58
-	 * @param IClientService $httpClientService
59
-	 * @param IDiscoveryService $discoveryService
60
-	 * @param IJobList $jobList
61
-	 * @param ICloudFederationProviderManager $federationProviderManager
62
-	 * @param ICloudFederationFactory $cloudFederationFactory
63
-	 */
64
-	public function __construct(
65
-		AddressHandler $addressHandler,
66
-		IClientService $httpClientService,
67
-		IDiscoveryService $discoveryService,
68
-		IJobList $jobList,
69
-		ICloudFederationProviderManager $federationProviderManager,
70
-		ICloudFederationFactory $cloudFederationFactory
71
-	) {
72
-		$this->addressHandler = $addressHandler;
73
-		$this->httpClientService = $httpClientService;
74
-		$this->discoveryService = $discoveryService;
75
-		$this->jobList = $jobList;
76
-		$this->federationProviderManager = $federationProviderManager;
77
-		$this->cloudFederationFactory = $cloudFederationFactory;
78
-	}
79
-
80
-	/**
81
-	 * send server-to-server share to remote server
82
-	 *
83
-	 * @param string $token
84
-	 * @param string $shareWith
85
-	 * @param string $name
86
-	 * @param int $remote_id
87
-	 * @param string $owner
88
-	 * @param string $ownerFederatedId
89
-	 * @param string $sharedBy
90
-	 * @param string $sharedByFederatedId
91
-	 * @return bool
92
-	 * @throws \OC\HintException
93
-	 * @throws \OC\ServerNotAvailableException
94
-	 */
95
-	public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId) {
96
-
97
-		list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
98
-
99
-		if ($user && $remote) {
100
-			$local = $this->addressHandler->generateRemoteURL();
101
-
102
-			$fields = array(
103
-				'shareWith' => $user,
104
-				'token' => $token,
105
-				'name' => $name,
106
-				'remoteId' => $remote_id,
107
-				'owner' => $owner,
108
-				'ownerFederatedId' => $ownerFederatedId,
109
-				'sharedBy' => $sharedBy,
110
-				'sharedByFederatedId' => $sharedByFederatedId,
111
-				'remote' => $local,
112
-			);
113
-
114
-			$result = $this->tryHttpPostToShareEndpoint($remote, '', $fields);
115
-			$status = json_decode($result['result'], true);
116
-
117
-			$ocsStatus = isset($status['ocs']);
118
-			$ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
119
-
120
-			if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) {
121
-				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
122
-				return true;
123
-			}
124
-
125
-		}
126
-
127
-		return false;
128
-	}
129
-
130
-	/**
131
-	 * ask owner to re-share the file with the given user
132
-	 *
133
-	 * @param string $token
134
-	 * @param int $id remote Id
135
-	 * @param int $shareId internal share Id
136
-	 * @param string $remote remote address of the owner
137
-	 * @param string $shareWith
138
-	 * @param int $permission
139
-	 * @param string $filename
140
-	 * @return bool
141
-	 * @throws \OC\HintException
142
-	 * @throws \OC\ServerNotAvailableException
143
-	 */
144
-	public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission, $filename) {
145
-
146
-		$fields = array(
147
-			'shareWith' => $shareWith,
148
-			'token' => $token,
149
-			'permission' => $permission,
150
-			'remoteId' => $shareId,
151
-		);
152
-
153
-		$ocmFields = $fields;
154
-		$ocmFields['remoteId'] = $id;
155
-		$ocmFields['localId'] = $shareId;
156
-		$ocmFields['name'] = $filename;
157
-
158
-		$ocmResult = $this->tryOCMEndPoint($remote, $ocmFields, 'reshare');
159
-		if (is_array($ocmResult) && isset($ocmResult['token']) && isset($ocmResult['providerId'])) {
160
-			return [$ocmResult['token'], $ocmResult['providerId']];
161
-		}
162
-
163
-		$result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
164
-		$status = json_decode($result['result'], true);
165
-
166
-		$httpRequestSuccessful = $result['success'];
167
-		$ocsCallSuccessful = $status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200;
168
-		$validToken = isset($status['ocs']['data']['token']) && is_string($status['ocs']['data']['token']);
169
-		$validRemoteId = isset($status['ocs']['data']['remoteId']);
170
-
171
-		if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
172
-			return [
173
-				$status['ocs']['data']['token'],
174
-				(int)$status['ocs']['data']['remoteId']
175
-			];
176
-		}
177
-
178
-		return false;
179
-	}
180
-
181
-	/**
182
-	 * send server-to-server unshare to remote server
183
-	 *
184
-	 * @param string $remote url
185
-	 * @param int $id share id
186
-	 * @param string $token
187
-	 * @return bool
188
-	 */
189
-	public function sendRemoteUnShare($remote, $id, $token) {
190
-		$this->sendUpdateToRemote($remote, $id, $token, 'unshare');
191
-	}
192
-
193
-	/**
194
-	 * send server-to-server unshare to remote server
195
-	 *
196
-	 * @param string $remote url
197
-	 * @param int $id share id
198
-	 * @param string $token
199
-	 * @return bool
200
-	 */
201
-	public function sendRevokeShare($remote, $id, $token) {
202
-		$this->sendUpdateToRemote($remote, $id, $token, 'reshare_undo');
203
-	}
204
-
205
-	/**
206
-	 * send notification to remote server if the permissions was changed
207
-	 *
208
-	 * @param string $remote
209
-	 * @param int $remoteId
210
-	 * @param string $token
211
-	 * @param int $permissions
212
-	 * @return bool
213
-	 */
214
-	public function sendPermissionChange($remote, $remoteId, $token, $permissions) {
215
-		$this->sendUpdateToRemote($remote, $remoteId, $token, 'permissions', ['permissions' => $permissions]);
216
-	}
217
-
218
-	/**
219
-	 * forward accept reShare to remote server
220
-	 *
221
-	 * @param string $remote
222
-	 * @param int $remoteId
223
-	 * @param string $token
224
-	 */
225
-	public function sendAcceptShare($remote, $remoteId, $token) {
226
-		$this->sendUpdateToRemote($remote, $remoteId, $token, 'accept');
227
-	}
228
-
229
-	/**
230
-	 * forward decline reShare to remote server
231
-	 *
232
-	 * @param string $remote
233
-	 * @param int $remoteId
234
-	 * @param string $token
235
-	 */
236
-	public function sendDeclineShare($remote, $remoteId, $token) {
237
-		$this->sendUpdateToRemote($remote, $remoteId, $token, 'decline');
238
-	}
239
-
240
-	/**
241
-	 * inform remote server whether server-to-server share was accepted/declined
242
-	 *
243
-	 * @param string $remote
244
-	 * @param string $token
245
-	 * @param int $remoteId Share id on the remote host
246
-	 * @param string $action possible actions: accept, decline, unshare, revoke, permissions
247
-	 * @param array $data
248
-	 * @param int $try
249
-	 * @return boolean
250
-	 */
251
-	public function sendUpdateToRemote($remote, $remoteId, $token, $action, $data = [], $try = 0) {
252
-
253
-		$fields = [
254
-			'token' => $token,
255
-			'remoteId' => $remoteId
256
-			];
257
-		foreach ($data as $key => $value) {
258
-			$fields[$key] = $value;
259
-		}
260
-
261
-		$result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action);
262
-		$status = json_decode($result['result'], true);
263
-
264
-		if ($result['success'] &&
265
-			($status['ocs']['meta']['statuscode'] === 100 ||
266
-				$status['ocs']['meta']['statuscode'] === 200
267
-			)
268
-		) {
269
-			return true;
270
-		} elseif ($try === 0) {
271
-			// only add new job on first try
272
-			$this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\RetryJob',
273
-				[
274
-					'remote' => $remote,
275
-					'remoteId' => $remoteId,
276
-					'token' => $token,
277
-					'action' => $action,
278
-					'data' => json_encode($data),
279
-					'try' => $try,
280
-					'lastRun' => $this->getTimestamp()
281
-				]
282
-			);
283
-		}
284
-
285
-		return false;
286
-	}
287
-
288
-
289
-	/**
290
-	 * return current timestamp
291
-	 *
292
-	 * @return int
293
-	 */
294
-	protected function getTimestamp() {
295
-		return time();
296
-	}
297
-
298
-	/**
299
-	 * try http post with the given protocol, if no protocol is given we pick
300
-	 * the secure one (https)
301
-	 *
302
-	 * @param string $remoteDomain
303
-	 * @param string $urlSuffix
304
-	 * @param array $fields post parameters
305
-	 * @param string $action define the action (possible values: share, reshare, accept, decline, unshare, revoke, permissions)
306
-	 * @return array
307
-	 * @throws \Exception
308
-	 */
309
-	protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") {
310
-
311
-		if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
312
-			$remoteDomain = 'https://' . $remoteDomain;
313
-		}
314
-
315
-		$result = [
316
-			'success' => false,
317
-			'result' => '',
318
-		];
319
-
320
-		// if possible we use the new OCM API
321
-		$ocmResult = $this->tryOCMEndPoint($remoteDomain, $fields, $action);
322
-		if (is_array($ocmResult)) {
323
-			$result['success'] = true;
324
-			$result['result'] = json_encode([
325
-				'ocs' => ['meta' => ['statuscode' => 200]]]);
326
-			return $result;
327
-		}
328
-
329
-		return $this->tryLegacyEndPoint($remoteDomain, $urlSuffix, $fields);
330
-	}
331
-
332
-	/**
333
-	 * try old federated sharing API if the OCM api doesn't work
334
-	 *
335
-	 * @param $remoteDomain
336
-	 * @param $urlSuffix
337
-	 * @param array $fields
338
-	 * @return mixed
339
-	 * @throws \Exception
340
-	 */
341
-	protected function tryLegacyEndPoint($remoteDomain, $urlSuffix, array $fields) {
342
-
343
-		$result = [
344
-			'success' => false,
345
-			'result' => '',
346
-		];
347
-
348
-		// Fall back to old API
349
-		$client = $this->httpClientService->newClient();
350
-		$federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING');
351
-		$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
352
-		try {
353
-			$response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
354
-				'body' => $fields,
355
-				'timeout' => 10,
356
-				'connect_timeout' => 10,
357
-			]);
358
-			$result['result'] = $response->getBody();
359
-			$result['success'] = true;
360
-		} catch (\Exception $e) {
361
-			// if flat re-sharing is not supported by the remote server
362
-			// we re-throw the exception and fall back to the old behaviour.
363
-			// (flat re-shares has been introduced in Nextcloud 9.1)
364
-			if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
365
-				throw $e;
366
-			}
367
-		}
368
-
369
-		return $result;
370
-
371
-	}
372
-
373
-	/**
374
-	 * check if server supports the new OCM api and ask for the correct end-point
375
-	 *
376
-	 * @param string $url
377
-	 * @return string
378
-	 */
379
-	protected function getOCMEndPoint($url) {
380
-		$client = $this->httpClientService->newClient();
381
-		try {
382
-			$response = $client->get($url, ['timeout' => 10, 'connect_timeout' => 10]);
383
-		} catch (\Exception $e) {
384
-			return '';
385
-		}
386
-
387
-		$result = $response->getBody();
388
-		$result = json_decode($result, true);
389
-
390
-		if (isset($result['end-point'])) {
391
-			return $result['end-point'];
392
-		}
393
-
394
-		return '';
395
-	}
396
-
397
-	/**
398
-	 * send action regarding federated sharing to the remote server using the OCM API
399
-	 *
400
-	 * @param $remoteDomain
401
-	 * @param $fields
402
-	 * @param $action
403
-	 *
404
-	 * @return bool
405
-	 */
406
-	protected function tryOCMEndPoint($remoteDomain, $fields, $action) {
407
-		switch ($action) {
408
-			case 'share':
409
-				$share = $this->cloudFederationFactory->getCloudFederationShare(
410
-					$fields['shareWith'] . '@' . $remoteDomain,
411
-					$fields['name'],
412
-					'',
413
-					$fields['remoteId'],
414
-					$fields['ownerFederatedId'],
415
-					$fields['owner'],
416
-					$fields['sharedByFederatedId'],
417
-					$fields['sharedBy'],
418
-					$fields['token'],
419
-					'user',
420
-					'file'
421
-				);
422
-				return $this->federationProviderManager->sendShare($share);
423
-			case 'reshare':
424
-				// ask owner to reshare a file
425
-				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
426
-				$notification->setMessage('REQUEST_RESHARE',
427
-					'file',
428
-					$fields['remoteId'],
429
-					[
430
-						'sharedSecret' => $fields['token'],
431
-						'shareWith' => $fields['shareWith'],
432
-						'senderId' => $fields['localId'],
433
-						'message' => 'Ask owner to reshare the file'
434
-					]
435
-				);
436
-				return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
437
-			case 'unshare':
438
-				//owner unshares the file from the recipient again
439
-				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
440
-				$notification->setMessage('SHARE_UNSHARED',
441
-					'file',
442
-					$fields['remoteId'],
443
-					[
444
-						'sharedSecret' => $fields['token'],
445
-						'messgage' => 'file is no longer shared with you'
446
-					]
447
-				);
448
-				return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
449
-			case 'reshare_undo':
450
-				// if a reshare was unshared we send the information to the initiator/owner
451
-				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
452
-				$notification->setMessage('RESHARE_UNDO',
453
-					'file',
454
-					$fields['remoteId'],
455
-					[
456
-						'sharedSecret' => $fields['token'],
457
-						'message' => 'reshare was revoked'
458
-					]
459
-				);
460
-				return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
461
-		}
462
-
463
-		return false;
464
-
465
-	}
36
+    const RESPONSE_FORMAT = 'json'; // default response format for ocs calls
37
+
38
+    /** @var AddressHandler */
39
+    private $addressHandler;
40
+
41
+    /** @var IClientService */
42
+    private $httpClientService;
43
+
44
+    /** @var IDiscoveryService */
45
+    private $discoveryService;
46
+
47
+    /** @var IJobList  */
48
+    private $jobList;
49
+
50
+    /** @var ICloudFederationProviderManager */
51
+    private $federationProviderManager;
52
+
53
+    /** @var ICloudFederationFactory */
54
+    private $cloudFederationFactory;
55
+
56
+    /**
57
+     * @param AddressHandler $addressHandler
58
+     * @param IClientService $httpClientService
59
+     * @param IDiscoveryService $discoveryService
60
+     * @param IJobList $jobList
61
+     * @param ICloudFederationProviderManager $federationProviderManager
62
+     * @param ICloudFederationFactory $cloudFederationFactory
63
+     */
64
+    public function __construct(
65
+        AddressHandler $addressHandler,
66
+        IClientService $httpClientService,
67
+        IDiscoveryService $discoveryService,
68
+        IJobList $jobList,
69
+        ICloudFederationProviderManager $federationProviderManager,
70
+        ICloudFederationFactory $cloudFederationFactory
71
+    ) {
72
+        $this->addressHandler = $addressHandler;
73
+        $this->httpClientService = $httpClientService;
74
+        $this->discoveryService = $discoveryService;
75
+        $this->jobList = $jobList;
76
+        $this->federationProviderManager = $federationProviderManager;
77
+        $this->cloudFederationFactory = $cloudFederationFactory;
78
+    }
79
+
80
+    /**
81
+     * send server-to-server share to remote server
82
+     *
83
+     * @param string $token
84
+     * @param string $shareWith
85
+     * @param string $name
86
+     * @param int $remote_id
87
+     * @param string $owner
88
+     * @param string $ownerFederatedId
89
+     * @param string $sharedBy
90
+     * @param string $sharedByFederatedId
91
+     * @return bool
92
+     * @throws \OC\HintException
93
+     * @throws \OC\ServerNotAvailableException
94
+     */
95
+    public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId) {
96
+
97
+        list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
98
+
99
+        if ($user && $remote) {
100
+            $local = $this->addressHandler->generateRemoteURL();
101
+
102
+            $fields = array(
103
+                'shareWith' => $user,
104
+                'token' => $token,
105
+                'name' => $name,
106
+                'remoteId' => $remote_id,
107
+                'owner' => $owner,
108
+                'ownerFederatedId' => $ownerFederatedId,
109
+                'sharedBy' => $sharedBy,
110
+                'sharedByFederatedId' => $sharedByFederatedId,
111
+                'remote' => $local,
112
+            );
113
+
114
+            $result = $this->tryHttpPostToShareEndpoint($remote, '', $fields);
115
+            $status = json_decode($result['result'], true);
116
+
117
+            $ocsStatus = isset($status['ocs']);
118
+            $ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
119
+
120
+            if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) {
121
+                \OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
122
+                return true;
123
+            }
124
+
125
+        }
126
+
127
+        return false;
128
+    }
129
+
130
+    /**
131
+     * ask owner to re-share the file with the given user
132
+     *
133
+     * @param string $token
134
+     * @param int $id remote Id
135
+     * @param int $shareId internal share Id
136
+     * @param string $remote remote address of the owner
137
+     * @param string $shareWith
138
+     * @param int $permission
139
+     * @param string $filename
140
+     * @return bool
141
+     * @throws \OC\HintException
142
+     * @throws \OC\ServerNotAvailableException
143
+     */
144
+    public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission, $filename) {
145
+
146
+        $fields = array(
147
+            'shareWith' => $shareWith,
148
+            'token' => $token,
149
+            'permission' => $permission,
150
+            'remoteId' => $shareId,
151
+        );
152
+
153
+        $ocmFields = $fields;
154
+        $ocmFields['remoteId'] = $id;
155
+        $ocmFields['localId'] = $shareId;
156
+        $ocmFields['name'] = $filename;
157
+
158
+        $ocmResult = $this->tryOCMEndPoint($remote, $ocmFields, 'reshare');
159
+        if (is_array($ocmResult) && isset($ocmResult['token']) && isset($ocmResult['providerId'])) {
160
+            return [$ocmResult['token'], $ocmResult['providerId']];
161
+        }
162
+
163
+        $result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
164
+        $status = json_decode($result['result'], true);
165
+
166
+        $httpRequestSuccessful = $result['success'];
167
+        $ocsCallSuccessful = $status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200;
168
+        $validToken = isset($status['ocs']['data']['token']) && is_string($status['ocs']['data']['token']);
169
+        $validRemoteId = isset($status['ocs']['data']['remoteId']);
170
+
171
+        if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
172
+            return [
173
+                $status['ocs']['data']['token'],
174
+                (int)$status['ocs']['data']['remoteId']
175
+            ];
176
+        }
177
+
178
+        return false;
179
+    }
180
+
181
+    /**
182
+     * send server-to-server unshare to remote server
183
+     *
184
+     * @param string $remote url
185
+     * @param int $id share id
186
+     * @param string $token
187
+     * @return bool
188
+     */
189
+    public function sendRemoteUnShare($remote, $id, $token) {
190
+        $this->sendUpdateToRemote($remote, $id, $token, 'unshare');
191
+    }
192
+
193
+    /**
194
+     * send server-to-server unshare to remote server
195
+     *
196
+     * @param string $remote url
197
+     * @param int $id share id
198
+     * @param string $token
199
+     * @return bool
200
+     */
201
+    public function sendRevokeShare($remote, $id, $token) {
202
+        $this->sendUpdateToRemote($remote, $id, $token, 'reshare_undo');
203
+    }
204
+
205
+    /**
206
+     * send notification to remote server if the permissions was changed
207
+     *
208
+     * @param string $remote
209
+     * @param int $remoteId
210
+     * @param string $token
211
+     * @param int $permissions
212
+     * @return bool
213
+     */
214
+    public function sendPermissionChange($remote, $remoteId, $token, $permissions) {
215
+        $this->sendUpdateToRemote($remote, $remoteId, $token, 'permissions', ['permissions' => $permissions]);
216
+    }
217
+
218
+    /**
219
+     * forward accept reShare to remote server
220
+     *
221
+     * @param string $remote
222
+     * @param int $remoteId
223
+     * @param string $token
224
+     */
225
+    public function sendAcceptShare($remote, $remoteId, $token) {
226
+        $this->sendUpdateToRemote($remote, $remoteId, $token, 'accept');
227
+    }
228
+
229
+    /**
230
+     * forward decline reShare to remote server
231
+     *
232
+     * @param string $remote
233
+     * @param int $remoteId
234
+     * @param string $token
235
+     */
236
+    public function sendDeclineShare($remote, $remoteId, $token) {
237
+        $this->sendUpdateToRemote($remote, $remoteId, $token, 'decline');
238
+    }
239
+
240
+    /**
241
+     * inform remote server whether server-to-server share was accepted/declined
242
+     *
243
+     * @param string $remote
244
+     * @param string $token
245
+     * @param int $remoteId Share id on the remote host
246
+     * @param string $action possible actions: accept, decline, unshare, revoke, permissions
247
+     * @param array $data
248
+     * @param int $try
249
+     * @return boolean
250
+     */
251
+    public function sendUpdateToRemote($remote, $remoteId, $token, $action, $data = [], $try = 0) {
252
+
253
+        $fields = [
254
+            'token' => $token,
255
+            'remoteId' => $remoteId
256
+            ];
257
+        foreach ($data as $key => $value) {
258
+            $fields[$key] = $value;
259
+        }
260
+
261
+        $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action);
262
+        $status = json_decode($result['result'], true);
263
+
264
+        if ($result['success'] &&
265
+            ($status['ocs']['meta']['statuscode'] === 100 ||
266
+                $status['ocs']['meta']['statuscode'] === 200
267
+            )
268
+        ) {
269
+            return true;
270
+        } elseif ($try === 0) {
271
+            // only add new job on first try
272
+            $this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\RetryJob',
273
+                [
274
+                    'remote' => $remote,
275
+                    'remoteId' => $remoteId,
276
+                    'token' => $token,
277
+                    'action' => $action,
278
+                    'data' => json_encode($data),
279
+                    'try' => $try,
280
+                    'lastRun' => $this->getTimestamp()
281
+                ]
282
+            );
283
+        }
284
+
285
+        return false;
286
+    }
287
+
288
+
289
+    /**
290
+     * return current timestamp
291
+     *
292
+     * @return int
293
+     */
294
+    protected function getTimestamp() {
295
+        return time();
296
+    }
297
+
298
+    /**
299
+     * try http post with the given protocol, if no protocol is given we pick
300
+     * the secure one (https)
301
+     *
302
+     * @param string $remoteDomain
303
+     * @param string $urlSuffix
304
+     * @param array $fields post parameters
305
+     * @param string $action define the action (possible values: share, reshare, accept, decline, unshare, revoke, permissions)
306
+     * @return array
307
+     * @throws \Exception
308
+     */
309
+    protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") {
310
+
311
+        if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
312
+            $remoteDomain = 'https://' . $remoteDomain;
313
+        }
314
+
315
+        $result = [
316
+            'success' => false,
317
+            'result' => '',
318
+        ];
319
+
320
+        // if possible we use the new OCM API
321
+        $ocmResult = $this->tryOCMEndPoint($remoteDomain, $fields, $action);
322
+        if (is_array($ocmResult)) {
323
+            $result['success'] = true;
324
+            $result['result'] = json_encode([
325
+                'ocs' => ['meta' => ['statuscode' => 200]]]);
326
+            return $result;
327
+        }
328
+
329
+        return $this->tryLegacyEndPoint($remoteDomain, $urlSuffix, $fields);
330
+    }
331
+
332
+    /**
333
+     * try old federated sharing API if the OCM api doesn't work
334
+     *
335
+     * @param $remoteDomain
336
+     * @param $urlSuffix
337
+     * @param array $fields
338
+     * @return mixed
339
+     * @throws \Exception
340
+     */
341
+    protected function tryLegacyEndPoint($remoteDomain, $urlSuffix, array $fields) {
342
+
343
+        $result = [
344
+            'success' => false,
345
+            'result' => '',
346
+        ];
347
+
348
+        // Fall back to old API
349
+        $client = $this->httpClientService->newClient();
350
+        $federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING');
351
+        $endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
352
+        try {
353
+            $response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
354
+                'body' => $fields,
355
+                'timeout' => 10,
356
+                'connect_timeout' => 10,
357
+            ]);
358
+            $result['result'] = $response->getBody();
359
+            $result['success'] = true;
360
+        } catch (\Exception $e) {
361
+            // if flat re-sharing is not supported by the remote server
362
+            // we re-throw the exception and fall back to the old behaviour.
363
+            // (flat re-shares has been introduced in Nextcloud 9.1)
364
+            if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
365
+                throw $e;
366
+            }
367
+        }
368
+
369
+        return $result;
370
+
371
+    }
372
+
373
+    /**
374
+     * check if server supports the new OCM api and ask for the correct end-point
375
+     *
376
+     * @param string $url
377
+     * @return string
378
+     */
379
+    protected function getOCMEndPoint($url) {
380
+        $client = $this->httpClientService->newClient();
381
+        try {
382
+            $response = $client->get($url, ['timeout' => 10, 'connect_timeout' => 10]);
383
+        } catch (\Exception $e) {
384
+            return '';
385
+        }
386
+
387
+        $result = $response->getBody();
388
+        $result = json_decode($result, true);
389
+
390
+        if (isset($result['end-point'])) {
391
+            return $result['end-point'];
392
+        }
393
+
394
+        return '';
395
+    }
396
+
397
+    /**
398
+     * send action regarding federated sharing to the remote server using the OCM API
399
+     *
400
+     * @param $remoteDomain
401
+     * @param $fields
402
+     * @param $action
403
+     *
404
+     * @return bool
405
+     */
406
+    protected function tryOCMEndPoint($remoteDomain, $fields, $action) {
407
+        switch ($action) {
408
+            case 'share':
409
+                $share = $this->cloudFederationFactory->getCloudFederationShare(
410
+                    $fields['shareWith'] . '@' . $remoteDomain,
411
+                    $fields['name'],
412
+                    '',
413
+                    $fields['remoteId'],
414
+                    $fields['ownerFederatedId'],
415
+                    $fields['owner'],
416
+                    $fields['sharedByFederatedId'],
417
+                    $fields['sharedBy'],
418
+                    $fields['token'],
419
+                    'user',
420
+                    'file'
421
+                );
422
+                return $this->federationProviderManager->sendShare($share);
423
+            case 'reshare':
424
+                // ask owner to reshare a file
425
+                $notification = $this->cloudFederationFactory->getCloudFederationNotification();
426
+                $notification->setMessage('REQUEST_RESHARE',
427
+                    'file',
428
+                    $fields['remoteId'],
429
+                    [
430
+                        'sharedSecret' => $fields['token'],
431
+                        'shareWith' => $fields['shareWith'],
432
+                        'senderId' => $fields['localId'],
433
+                        'message' => 'Ask owner to reshare the file'
434
+                    ]
435
+                );
436
+                return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
437
+            case 'unshare':
438
+                //owner unshares the file from the recipient again
439
+                $notification = $this->cloudFederationFactory->getCloudFederationNotification();
440
+                $notification->setMessage('SHARE_UNSHARED',
441
+                    'file',
442
+                    $fields['remoteId'],
443
+                    [
444
+                        'sharedSecret' => $fields['token'],
445
+                        'messgage' => 'file is no longer shared with you'
446
+                    ]
447
+                );
448
+                return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
449
+            case 'reshare_undo':
450
+                // if a reshare was unshared we send the information to the initiator/owner
451
+                $notification = $this->cloudFederationFactory->getCloudFederationNotification();
452
+                $notification->setMessage('RESHARE_UNDO',
453
+                    'file',
454
+                    $fields['remoteId'],
455
+                    [
456
+                        'sharedSecret' => $fields['token'],
457
+                        'message' => 'reshare was revoked'
458
+                    ]
459
+                );
460
+                return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
461
+        }
462
+
463
+        return false;
464
+
465
+    }
466 466
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/AppInfo/Application.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -39,114 +39,114 @@
 block discarded – undo
39 39
 
40 40
 class Application extends App {
41 41
 
42
-	/** @var FederatedShareProvider */
43
-	protected $federatedShareProvider;
42
+    /** @var FederatedShareProvider */
43
+    protected $federatedShareProvider;
44 44
 
45
-	public function __construct() {
46
-		parent::__construct('federatedfilesharing');
45
+    public function __construct() {
46
+        parent::__construct('federatedfilesharing');
47 47
 
48
-		$container = $this->getContainer();
49
-		$server = $container->getServer();
48
+        $container = $this->getContainer();
49
+        $server = $container->getServer();
50 50
 
51
-		$cloudFederationManager = $server->getCloudFederationProviderManager();
52
-		$cloudFederationManager->addCloudFederationProvider('file',
53
-			'Federated Files Sharing',
54
-			function() use ($container) {
55
-				$server = $container->getServer();
56
-				return new CloudFederationProviderFiles(
57
-					$server->getAppManager(),
58
-					$server->query(FederatedShareProvider::class),
59
-					$server->query(AddressHandler::class),
60
-					$server->getLogger(),
61
-					$server->getUserManager(),
62
-					$server->getCloudIdManager(),
63
-					$server->getActivityManager(),
64
-					$server->getNotificationManager(),
65
-					$server->getURLGenerator(),
66
-					$server->getCloudFederationFactory(),
67
-					$server->getCloudFederationProviderManager(),
68
-					$server->getDatabaseConnection()
69
-				);
70
-			});
51
+        $cloudFederationManager = $server->getCloudFederationProviderManager();
52
+        $cloudFederationManager->addCloudFederationProvider('file',
53
+            'Federated Files Sharing',
54
+            function() use ($container) {
55
+                $server = $container->getServer();
56
+                return new CloudFederationProviderFiles(
57
+                    $server->getAppManager(),
58
+                    $server->query(FederatedShareProvider::class),
59
+                    $server->query(AddressHandler::class),
60
+                    $server->getLogger(),
61
+                    $server->getUserManager(),
62
+                    $server->getCloudIdManager(),
63
+                    $server->getActivityManager(),
64
+                    $server->getNotificationManager(),
65
+                    $server->getURLGenerator(),
66
+                    $server->getCloudFederationFactory(),
67
+                    $server->getCloudFederationProviderManager(),
68
+                    $server->getDatabaseConnection()
69
+                );
70
+            });
71 71
 
72
-		$container->registerService('RequestHandlerController', function(SimpleContainer $c) use ($server) {
73
-			$addressHandler = new AddressHandler(
74
-				$server->getURLGenerator(),
75
-				$server->getL10N('federatedfilesharing'),
76
-				$server->getCloudIdManager()
77
-			);
78
-			$notification = new Notifications(
79
-				$addressHandler,
80
-				$server->getHTTPClientService(),
81
-				$server->query(\OCP\OCS\IDiscoveryService::class),
82
-				\OC::$server->getJobList(),
83
-				\OC::$server->getCloudFederationProviderManager(),
84
-				\OC::$server->getCloudFederationFactory()
85
-			);
86
-			return new RequestHandlerController(
87
-				$c->query('AppName'),
88
-				$server->getRequest(),
89
-				$this->getFederatedShareProvider(),
90
-				$server->getDatabaseConnection(),
91
-				$server->getShareManager(),
92
-				$notification,
93
-				$addressHandler,
94
-				$server->getUserManager(),
95
-				$server->getCloudIdManager(),
96
-				$server->getLogger(),
97
-				$server->getCloudFederationFactory(),
98
-				$server->getCloudFederationProviderManager()
99
-			);
100
-		});
101
-	}
72
+        $container->registerService('RequestHandlerController', function(SimpleContainer $c) use ($server) {
73
+            $addressHandler = new AddressHandler(
74
+                $server->getURLGenerator(),
75
+                $server->getL10N('federatedfilesharing'),
76
+                $server->getCloudIdManager()
77
+            );
78
+            $notification = new Notifications(
79
+                $addressHandler,
80
+                $server->getHTTPClientService(),
81
+                $server->query(\OCP\OCS\IDiscoveryService::class),
82
+                \OC::$server->getJobList(),
83
+                \OC::$server->getCloudFederationProviderManager(),
84
+                \OC::$server->getCloudFederationFactory()
85
+            );
86
+            return new RequestHandlerController(
87
+                $c->query('AppName'),
88
+                $server->getRequest(),
89
+                $this->getFederatedShareProvider(),
90
+                $server->getDatabaseConnection(),
91
+                $server->getShareManager(),
92
+                $notification,
93
+                $addressHandler,
94
+                $server->getUserManager(),
95
+                $server->getCloudIdManager(),
96
+                $server->getLogger(),
97
+                $server->getCloudFederationFactory(),
98
+                $server->getCloudFederationProviderManager()
99
+            );
100
+        });
101
+    }
102 102
 
103
-	/**
104
-	 * get instance of federated share provider
105
-	 *
106
-	 * @return FederatedShareProvider
107
-	 */
108
-	public function getFederatedShareProvider() {
109
-		if ($this->federatedShareProvider === null) {
110
-			$this->initFederatedShareProvider();
111
-		}
112
-		return $this->federatedShareProvider;
113
-	}
103
+    /**
104
+     * get instance of federated share provider
105
+     *
106
+     * @return FederatedShareProvider
107
+     */
108
+    public function getFederatedShareProvider() {
109
+        if ($this->federatedShareProvider === null) {
110
+            $this->initFederatedShareProvider();
111
+        }
112
+        return $this->federatedShareProvider;
113
+    }
114 114
 
115
-	/**
116
-	 * initialize federated share provider
117
-	 */
118
-	protected function initFederatedShareProvider() {
119
-		$c = $this->getContainer();
120
-		$addressHandler = new \OCA\FederatedFileSharing\AddressHandler(
121
-			\OC::$server->getURLGenerator(),
122
-			\OC::$server->getL10N('federatedfilesharing'),
123
-			\OC::$server->getCloudIdManager()
124
-		);
125
-		$notifications = new \OCA\FederatedFileSharing\Notifications(
126
-			$addressHandler,
127
-			\OC::$server->getHTTPClientService(),
128
-			\OC::$server->query(\OCP\OCS\IDiscoveryService::class),
129
-			\OC::$server->getJobList(),
130
-			\OC::$server->getCloudFederationProviderManager(),
131
-			\OC::$server->getCloudFederationFactory()
132
-		);
133
-		$tokenHandler = new \OCA\FederatedFileSharing\TokenHandler(
134
-			\OC::$server->getSecureRandom()
135
-		);
115
+    /**
116
+     * initialize federated share provider
117
+     */
118
+    protected function initFederatedShareProvider() {
119
+        $c = $this->getContainer();
120
+        $addressHandler = new \OCA\FederatedFileSharing\AddressHandler(
121
+            \OC::$server->getURLGenerator(),
122
+            \OC::$server->getL10N('federatedfilesharing'),
123
+            \OC::$server->getCloudIdManager()
124
+        );
125
+        $notifications = new \OCA\FederatedFileSharing\Notifications(
126
+            $addressHandler,
127
+            \OC::$server->getHTTPClientService(),
128
+            \OC::$server->query(\OCP\OCS\IDiscoveryService::class),
129
+            \OC::$server->getJobList(),
130
+            \OC::$server->getCloudFederationProviderManager(),
131
+            \OC::$server->getCloudFederationFactory()
132
+        );
133
+        $tokenHandler = new \OCA\FederatedFileSharing\TokenHandler(
134
+            \OC::$server->getSecureRandom()
135
+        );
136 136
 
137
-		$this->federatedShareProvider = new \OCA\FederatedFileSharing\FederatedShareProvider(
138
-			\OC::$server->getDatabaseConnection(),
139
-			$addressHandler,
140
-			$notifications,
141
-			$tokenHandler,
142
-			\OC::$server->getL10N('federatedfilesharing'),
143
-			\OC::$server->getLogger(),
144
-			\OC::$server->getLazyRootFolder(),
145
-			\OC::$server->getConfig(),
146
-			\OC::$server->getUserManager(),
147
-			\OC::$server->getCloudIdManager(),
148
-			$c->query(IConfig::class)
149
-		);
150
-	}
137
+        $this->federatedShareProvider = new \OCA\FederatedFileSharing\FederatedShareProvider(
138
+            \OC::$server->getDatabaseConnection(),
139
+            $addressHandler,
140
+            $notifications,
141
+            $tokenHandler,
142
+            \OC::$server->getL10N('federatedfilesharing'),
143
+            \OC::$server->getLogger(),
144
+            \OC::$server->getLazyRootFolder(),
145
+            \OC::$server->getConfig(),
146
+            \OC::$server->getUserManager(),
147
+            \OC::$server->getCloudIdManager(),
148
+            $c->query(IConfig::class)
149
+        );
150
+    }
151 151
 
152 152
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/Controller/RequestHandlerController.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -450,7 +450,7 @@
 block discarded – undo
450 450
 	/**
451 451
 	 * translate Nextcloud permissions to OCM Permissions
452 452
 	 *
453
-	 * @param $ncPermissions
453
+	 * @param integer $ncPermissions
454 454
 	 * @return array
455 455
 	 */
456 456
 	protected function ncPermissions2ocmPermissions($ncPermissions) {
Please login to merge, or discard this patch.
Indentation   +450 added lines, -450 removed lines patch added patch discarded remove patch
@@ -52,454 +52,454 @@
 block discarded – undo
52 52
 
53 53
 class RequestHandlerController extends OCSController {
54 54
 
55
-	/** @var FederatedShareProvider */
56
-	private $federatedShareProvider;
57
-
58
-	/** @var IDBConnection */
59
-	private $connection;
60
-
61
-	/** @var Share\IManager */
62
-	private $shareManager;
63
-
64
-	/** @var Notifications */
65
-	private $notifications;
66
-
67
-	/** @var AddressHandler */
68
-	private $addressHandler;
69
-
70
-	/** @var  IUserManager */
71
-	private $userManager;
72
-
73
-	/** @var string */
74
-	private $shareTable = 'share';
75
-
76
-	/** @var ICloudIdManager */
77
-	private $cloudIdManager;
78
-
79
-	/** @var ILogger */
80
-	private $logger;
81
-
82
-	/** @var ICloudFederationFactory */
83
-	private $cloudFederationFactory;
84
-
85
-	/** @var ICloudFederationProviderManager */
86
-	private $cloudFederationProviderManager;
87
-
88
-	/**
89
-	 * Server2Server constructor.
90
-	 *
91
-	 * @param string $appName
92
-	 * @param IRequest $request
93
-	 * @param FederatedShareProvider $federatedShareProvider
94
-	 * @param IDBConnection $connection
95
-	 * @param Share\IManager $shareManager
96
-	 * @param Notifications $notifications
97
-	 * @param AddressHandler $addressHandler
98
-	 * @param IUserManager $userManager
99
-	 * @param ICloudIdManager $cloudIdManager
100
-	 * @param ILogger $logger
101
-	 * @param ICloudFederationFactory $cloudFederationFactory
102
-	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
103
-	 */
104
-	public function __construct($appName,
105
-								IRequest $request,
106
-								FederatedShareProvider $federatedShareProvider,
107
-								IDBConnection $connection,
108
-								Share\IManager $shareManager,
109
-								Notifications $notifications,
110
-								AddressHandler $addressHandler,
111
-								IUserManager $userManager,
112
-								ICloudIdManager $cloudIdManager,
113
-								ILogger $logger,
114
-								ICloudFederationFactory $cloudFederationFactory,
115
-								ICloudFederationProviderManager $cloudFederationProviderManager
116
-	) {
117
-		parent::__construct($appName, $request);
118
-
119
-		$this->federatedShareProvider = $federatedShareProvider;
120
-		$this->connection = $connection;
121
-		$this->shareManager = $shareManager;
122
-		$this->notifications = $notifications;
123
-		$this->addressHandler = $addressHandler;
124
-		$this->userManager = $userManager;
125
-		$this->cloudIdManager = $cloudIdManager;
126
-		$this->logger = $logger;
127
-		$this->cloudFederationFactory = $cloudFederationFactory;
128
-		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
129
-	}
130
-
131
-	/**
132
-	 * @NoCSRFRequired
133
-	 * @PublicPage
134
-	 *
135
-	 * create a new share
136
-	 *
137
-	 * @return Http\DataResponse
138
-	 * @throws OCSException
139
-	 */
140
-	public function createShare() {
141
-
142
-		$remote = isset($_POST['remote']) ? $_POST['remote'] : null;
143
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
144
-		$name = isset($_POST['name']) ? $_POST['name'] : null;
145
-		$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
146
-		$sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
147
-		$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
148
-		$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
149
-		$sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
150
-		$ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
151
-
152
-		if ($ownerFederatedId === null) {
153
-			$ownerFederatedId = $this->cloudIdManager->getCloudId($owner, $this->cleanupRemote($remote))->getId();
154
-		}
155
-		// if the owner of the share and the initiator are the same user
156
-		// we also complete the federated share ID for the initiator
157
-		if ($sharedByFederatedId === null && $owner === $sharedBy) {
158
-			$sharedByFederatedId = $ownerFederatedId;
159
-		}
160
-
161
-		$share = $this->cloudFederationFactory->getCloudFederationShare(
162
-			$shareWith,
163
-			$name,
164
-			'',
165
-			$remoteId,
166
-			$ownerFederatedId,
167
-			$owner,
168
-			$sharedByFederatedId,
169
-			$sharedBy,
170
-			$token,
171
-			'user',
172
-			'file'
173
-		);
174
-
175
-		try {
176
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
177
-			$provider->shareReceived($share);
178
-		} catch (ProviderDoesNotExistsException $e) {
179
-			throw new OCSException('Server does not support federated cloud sharing', 503);
180
-		} catch (ProviderCouldNotAddShareException $e) {
181
-			throw new OCSException($e->getMessage(), $e->getCode());
182
-		} catch (\Exception $e) {
183
-			throw new OCSException('internal server error, was not able to add share from ' . $remote, 500);
184
-		}
185
-
186
-		return new Http\DataResponse();
187
-	}
188
-
189
-	/**
190
-	 * @NoCSRFRequired
191
-	 * @PublicPage
192
-	 *
193
-	 * create re-share on behalf of another user
194
-	 *
195
-	 * @param int $id
196
-	 * @return Http\DataResponse
197
-	 * @throws OCSBadRequestException
198
-	 * @throws OCSException
199
-	 * @throws OCSForbiddenException
200
-	 */
201
-	public function reShare($id) {
202
-
203
-		$token = $this->request->getParam('token', null);
204
-		$shareWith = $this->request->getParam('shareWith', null);
205
-		$permission = (int)$this->request->getParam('permission', null);
206
-		$remoteId = (int)$this->request->getParam('remoteId', null);
207
-
208
-		if ($id === null ||
209
-			$token === null ||
210
-			$shareWith === null ||
211
-			$permission === null ||
212
-			$remoteId === null
213
-		) {
214
-			throw new OCSBadRequestException();
215
-		}
216
-
217
-		$notification = [
218
-			'sharedSecret' => $token,
219
-			'shareWith' => $shareWith,
220
-			'senderId' => $remoteId,
221
-			'message' => 'Recipient of a share ask the owner to reshare the file'
222
-		];
223
-
224
-		try {
225
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
226
-			list($newToken, $localId) = $provider->notificationReceived('REQUEST_RESHARE', $id, $notification);
227
-			return new Http\DataResponse([
228
-				'token' => $newToken,
229
-				'remoteId' => $localId
230
-			]);
231
-		} catch (ProviderDoesNotExistsException $e) {
232
-			throw new OCSException('Server does not support federated cloud sharing', 503);
233
-		} catch (ShareNotFound $e) {
234
-			$this->logger->debug('Share not found: ' . $e->getMessage());
235
-		} catch (\Exception $e) {
236
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
237
-		}
238
-
239
-		throw new OCSBadRequestException();
240
-	}
241
-
242
-
243
-	/**
244
-	 * @NoCSRFRequired
245
-	 * @PublicPage
246
-	 *
247
-	 * accept server-to-server share
248
-	 *
249
-	 * @param int $id
250
-	 * @return Http\DataResponse
251
-	 * @throws OCSException
252
-	 * @throws ShareNotFound
253
-	 * @throws \OC\HintException
254
-	 */
255
-	public function acceptShare($id) {
256
-
257
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
258
-
259
-		$notification = [
260
-			'sharedSecret' => $token,
261
-			'message' => 'Recipient accept the share'
262
-		];
263
-
264
-		try {
265
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
266
-			$provider->notificationReceived('SHARE_ACCEPTED', $id, $notification);
267
-		} catch (ProviderDoesNotExistsException $e) {
268
-			throw new OCSException('Server does not support federated cloud sharing', 503);
269
-		} catch (ShareNotFound $e) {
270
-			$this->logger->debug('Share not found: ' . $e->getMessage());
271
-		} catch (\Exception $e) {
272
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
273
-		}
274
-
275
-		return new Http\DataResponse();
276
-	}
277
-
278
-	/**
279
-	 * @NoCSRFRequired
280
-	 * @PublicPage
281
-	 *
282
-	 * decline server-to-server share
283
-	 *
284
-	 * @param int $id
285
-	 * @return Http\DataResponse
286
-	 * @throws OCSException
287
-	 */
288
-	public function declineShare($id) {
289
-
290
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
291
-
292
-		$notification = [
293
-			'sharedSecret' => $token,
294
-			'message' => 'Recipient declined the share'
295
-		];
296
-
297
-		try {
298
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
299
-			$provider->notificationReceived('SHARE_DECLINED', $id, $notification);
300
-		} catch (ProviderDoesNotExistsException $e) {
301
-			throw new OCSException('Server does not support federated cloud sharing', 503);
302
-		} catch (ShareNotFound $e) {
303
-			$this->logger->debug('Share not found: ' . $e->getMessage());
304
-		} catch (\Exception $e) {
305
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
306
-		}
307
-
308
-		return new Http\DataResponse();
309
-	}
310
-
311
-	/**
312
-	 * @NoCSRFRequired
313
-	 * @PublicPage
314
-	 *
315
-	 * remove server-to-server share if it was unshared by the owner
316
-	 *
317
-	 * @param int $id
318
-	 * @return Http\DataResponse
319
-	 * @throws OCSException
320
-	 */
321
-	public function unshare($id) {
322
-
323
-		if (!$this->isS2SEnabled()) {
324
-			throw new OCSException('Server does not support federated cloud sharing', 503);
325
-		}
326
-
327
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
328
-
329
-		try {
330
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
331
-			$notification = ['sharedSecret' => $token];
332
-			$provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
333
-		} catch (\Exception $e) {
334
-			$this->logger->debug('processing unshare notification failed: ' . $e->getMessage());
335
-		}
336
-
337
-		return new Http\DataResponse();
338
-	}
339
-
340
-	private function cleanupRemote($remote) {
341
-		$remote = substr($remote, strpos($remote, '://') + 3);
342
-
343
-		return rtrim($remote, '/');
344
-	}
345
-
346
-
347
-	/**
348
-	 * @NoCSRFRequired
349
-	 * @PublicPage
350
-	 *
351
-	 * federated share was revoked, either by the owner or the re-sharer
352
-	 *
353
-	 * @param int $id
354
-	 * @return Http\DataResponse
355
-	 * @throws OCSBadRequestException
356
-	 */
357
-	public function revoke($id) {
358
-
359
-		$token = $this->request->getParam('token');
360
-
361
-		try {
362
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
363
-			$notification = ['sharedSecret' => $token];
364
-			$provider->notificationReceived('RESHARE_UNDO', $id, $notification);
365
-			return new Http\DataResponse();
366
-		} catch (\Exception $e) {
367
-			throw new OCSBadRequestException();
368
-		}
369
-
370
-	}
371
-
372
-	/**
373
-	 * get share
374
-	 *
375
-	 * @param int $id
376
-	 * @param string $token
377
-	 * @return array|bool
378
-	 */
379
-	protected function getShare($id, $token) {
380
-		$query = $this->connection->getQueryBuilder();
381
-		$query->select('*')->from($this->shareTable)
382
-			->where($query->expr()->eq('token', $query->createNamedParameter($token)))
383
-			->andWhere($query->expr()->eq('share_type', $query->createNamedParameter(FederatedShareProvider::SHARE_TYPE_REMOTE)))
384
-			->andWhere($query->expr()->eq('id', $query->createNamedParameter($id)));
385
-
386
-		$result = $query->execute()->fetchAll();
387
-
388
-		if (!empty($result) && isset($result[0])) {
389
-			return $result[0];
390
-		}
391
-
392
-		return false;
393
-	}
394
-
395
-	/**
396
-	 * check if server-to-server sharing is enabled
397
-	 *
398
-	 * @param bool $incoming
399
-	 * @return bool
400
-	 */
401
-	private function isS2SEnabled($incoming = false) {
402
-
403
-		$result = \OCP\App::isEnabled('files_sharing');
404
-
405
-		if ($incoming) {
406
-			$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
407
-		} else {
408
-			$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
409
-		}
410
-
411
-		return $result;
412
-	}
413
-
414
-	/**
415
-	 * @NoCSRFRequired
416
-	 * @PublicPage
417
-	 *
418
-	 * update share information to keep federated re-shares in sync
419
-	 *
420
-	 * @param int $id
421
-	 * @return Http\DataResponse
422
-	 * @throws OCSBadRequestException
423
-	 */
424
-	public function updatePermissions($id) {
425
-		$token = $this->request->getParam('token', null);
426
-		$ncPermissions = $this->request->getParam('permissions', null);
427
-
428
-		try {
429
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
430
-			$ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
431
-			$notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
432
-			$provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
433
-		} catch (\Exception $e) {
434
-			$this->logger->debug($e->getMessage());
435
-			throw new OCSBadRequestException();
436
-		}
437
-
438
-		return new Http\DataResponse();
439
-	}
440
-
441
-	/**
442
-	 * translate Nextcloud permissions to OCM Permissions
443
-	 *
444
-	 * @param $ncPermissions
445
-	 * @return array
446
-	 */
447
-	protected function ncPermissions2ocmPermissions($ncPermissions) {
448
-
449
-		$ocmPermissions = [];
450
-
451
-		if ($ncPermissions & Constants::PERMISSION_SHARE) {
452
-			$ocmPermissions[] = 'share';
453
-		}
454
-
455
-		if ($ncPermissions & Constants::PERMISSION_READ) {
456
-			$ocmPermissions[] = 'read';
457
-		}
458
-
459
-		if (($ncPermissions & Constants::PERMISSION_CREATE) ||
460
-			($ncPermissions & Constants::PERMISSION_UPDATE)) {
461
-			$ocmPermissions[] = 'write';
462
-		}
463
-
464
-		return $ocmPermissions;
465
-
466
-	}
467
-
468
-	/**
469
-	 * @NoCSRFRequired
470
-	 * @PublicPage
471
-	 *
472
-	 * change the owner of a server-to-server share
473
-	 *
474
-	 * @param int $id
475
-	 * @return Http\DataResponse
476
-	 * @throws \InvalidArgumentException
477
-	 * @throws OCSException
478
-	 */
479
-	public function move($id) {
480
-
481
-		if (!$this->isS2SEnabled()) {
482
-			throw new OCSException('Server does not support federated cloud sharing', 503);
483
-		}
484
-
485
-		$token = $this->request->getParam('token');
486
-		$remote = $this->request->getParam('remote');
487
-		$newRemoteId = $this->request->getParam('remote_id', $id);
488
-		$cloudId = $this->cloudIdManager->resolveCloudId($remote);
489
-
490
-		$qb = $this->connection->getQueryBuilder();
491
-		$query = $qb->update('share_external')
492
-			->set('remote', $qb->createNamedParameter($cloudId->getRemote()))
493
-			->set('owner', $qb->createNamedParameter($cloudId->getUser()))
494
-			->set('remote_id', $qb->createNamedParameter($newRemoteId))
495
-			->where($qb->expr()->eq('remote_id', $qb->createNamedParameter($id)))
496
-			->andWhere($qb->expr()->eq('share_token', $qb->createNamedParameter($token)));
497
-		$affected = $query->execute();
498
-
499
-		if ($affected > 0) {
500
-			return new Http\DataResponse(['remote' => $cloudId->getRemote(), 'owner' => $cloudId->getUser()]);
501
-		} else {
502
-			throw new OCSBadRequestException('Share not found or token invalid');
503
-		}
504
-	}
55
+    /** @var FederatedShareProvider */
56
+    private $federatedShareProvider;
57
+
58
+    /** @var IDBConnection */
59
+    private $connection;
60
+
61
+    /** @var Share\IManager */
62
+    private $shareManager;
63
+
64
+    /** @var Notifications */
65
+    private $notifications;
66
+
67
+    /** @var AddressHandler */
68
+    private $addressHandler;
69
+
70
+    /** @var  IUserManager */
71
+    private $userManager;
72
+
73
+    /** @var string */
74
+    private $shareTable = 'share';
75
+
76
+    /** @var ICloudIdManager */
77
+    private $cloudIdManager;
78
+
79
+    /** @var ILogger */
80
+    private $logger;
81
+
82
+    /** @var ICloudFederationFactory */
83
+    private $cloudFederationFactory;
84
+
85
+    /** @var ICloudFederationProviderManager */
86
+    private $cloudFederationProviderManager;
87
+
88
+    /**
89
+     * Server2Server constructor.
90
+     *
91
+     * @param string $appName
92
+     * @param IRequest $request
93
+     * @param FederatedShareProvider $federatedShareProvider
94
+     * @param IDBConnection $connection
95
+     * @param Share\IManager $shareManager
96
+     * @param Notifications $notifications
97
+     * @param AddressHandler $addressHandler
98
+     * @param IUserManager $userManager
99
+     * @param ICloudIdManager $cloudIdManager
100
+     * @param ILogger $logger
101
+     * @param ICloudFederationFactory $cloudFederationFactory
102
+     * @param ICloudFederationProviderManager $cloudFederationProviderManager
103
+     */
104
+    public function __construct($appName,
105
+                                IRequest $request,
106
+                                FederatedShareProvider $federatedShareProvider,
107
+                                IDBConnection $connection,
108
+                                Share\IManager $shareManager,
109
+                                Notifications $notifications,
110
+                                AddressHandler $addressHandler,
111
+                                IUserManager $userManager,
112
+                                ICloudIdManager $cloudIdManager,
113
+                                ILogger $logger,
114
+                                ICloudFederationFactory $cloudFederationFactory,
115
+                                ICloudFederationProviderManager $cloudFederationProviderManager
116
+    ) {
117
+        parent::__construct($appName, $request);
118
+
119
+        $this->federatedShareProvider = $federatedShareProvider;
120
+        $this->connection = $connection;
121
+        $this->shareManager = $shareManager;
122
+        $this->notifications = $notifications;
123
+        $this->addressHandler = $addressHandler;
124
+        $this->userManager = $userManager;
125
+        $this->cloudIdManager = $cloudIdManager;
126
+        $this->logger = $logger;
127
+        $this->cloudFederationFactory = $cloudFederationFactory;
128
+        $this->cloudFederationProviderManager = $cloudFederationProviderManager;
129
+    }
130
+
131
+    /**
132
+     * @NoCSRFRequired
133
+     * @PublicPage
134
+     *
135
+     * create a new share
136
+     *
137
+     * @return Http\DataResponse
138
+     * @throws OCSException
139
+     */
140
+    public function createShare() {
141
+
142
+        $remote = isset($_POST['remote']) ? $_POST['remote'] : null;
143
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
144
+        $name = isset($_POST['name']) ? $_POST['name'] : null;
145
+        $owner = isset($_POST['owner']) ? $_POST['owner'] : null;
146
+        $sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
147
+        $shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
148
+        $remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
149
+        $sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
150
+        $ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
151
+
152
+        if ($ownerFederatedId === null) {
153
+            $ownerFederatedId = $this->cloudIdManager->getCloudId($owner, $this->cleanupRemote($remote))->getId();
154
+        }
155
+        // if the owner of the share and the initiator are the same user
156
+        // we also complete the federated share ID for the initiator
157
+        if ($sharedByFederatedId === null && $owner === $sharedBy) {
158
+            $sharedByFederatedId = $ownerFederatedId;
159
+        }
160
+
161
+        $share = $this->cloudFederationFactory->getCloudFederationShare(
162
+            $shareWith,
163
+            $name,
164
+            '',
165
+            $remoteId,
166
+            $ownerFederatedId,
167
+            $owner,
168
+            $sharedByFederatedId,
169
+            $sharedBy,
170
+            $token,
171
+            'user',
172
+            'file'
173
+        );
174
+
175
+        try {
176
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
177
+            $provider->shareReceived($share);
178
+        } catch (ProviderDoesNotExistsException $e) {
179
+            throw new OCSException('Server does not support federated cloud sharing', 503);
180
+        } catch (ProviderCouldNotAddShareException $e) {
181
+            throw new OCSException($e->getMessage(), $e->getCode());
182
+        } catch (\Exception $e) {
183
+            throw new OCSException('internal server error, was not able to add share from ' . $remote, 500);
184
+        }
185
+
186
+        return new Http\DataResponse();
187
+    }
188
+
189
+    /**
190
+     * @NoCSRFRequired
191
+     * @PublicPage
192
+     *
193
+     * create re-share on behalf of another user
194
+     *
195
+     * @param int $id
196
+     * @return Http\DataResponse
197
+     * @throws OCSBadRequestException
198
+     * @throws OCSException
199
+     * @throws OCSForbiddenException
200
+     */
201
+    public function reShare($id) {
202
+
203
+        $token = $this->request->getParam('token', null);
204
+        $shareWith = $this->request->getParam('shareWith', null);
205
+        $permission = (int)$this->request->getParam('permission', null);
206
+        $remoteId = (int)$this->request->getParam('remoteId', null);
207
+
208
+        if ($id === null ||
209
+            $token === null ||
210
+            $shareWith === null ||
211
+            $permission === null ||
212
+            $remoteId === null
213
+        ) {
214
+            throw new OCSBadRequestException();
215
+        }
216
+
217
+        $notification = [
218
+            'sharedSecret' => $token,
219
+            'shareWith' => $shareWith,
220
+            'senderId' => $remoteId,
221
+            'message' => 'Recipient of a share ask the owner to reshare the file'
222
+        ];
223
+
224
+        try {
225
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
226
+            list($newToken, $localId) = $provider->notificationReceived('REQUEST_RESHARE', $id, $notification);
227
+            return new Http\DataResponse([
228
+                'token' => $newToken,
229
+                'remoteId' => $localId
230
+            ]);
231
+        } catch (ProviderDoesNotExistsException $e) {
232
+            throw new OCSException('Server does not support federated cloud sharing', 503);
233
+        } catch (ShareNotFound $e) {
234
+            $this->logger->debug('Share not found: ' . $e->getMessage());
235
+        } catch (\Exception $e) {
236
+            $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
237
+        }
238
+
239
+        throw new OCSBadRequestException();
240
+    }
241
+
242
+
243
+    /**
244
+     * @NoCSRFRequired
245
+     * @PublicPage
246
+     *
247
+     * accept server-to-server share
248
+     *
249
+     * @param int $id
250
+     * @return Http\DataResponse
251
+     * @throws OCSException
252
+     * @throws ShareNotFound
253
+     * @throws \OC\HintException
254
+     */
255
+    public function acceptShare($id) {
256
+
257
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
258
+
259
+        $notification = [
260
+            'sharedSecret' => $token,
261
+            'message' => 'Recipient accept the share'
262
+        ];
263
+
264
+        try {
265
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
266
+            $provider->notificationReceived('SHARE_ACCEPTED', $id, $notification);
267
+        } catch (ProviderDoesNotExistsException $e) {
268
+            throw new OCSException('Server does not support federated cloud sharing', 503);
269
+        } catch (ShareNotFound $e) {
270
+            $this->logger->debug('Share not found: ' . $e->getMessage());
271
+        } catch (\Exception $e) {
272
+            $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
273
+        }
274
+
275
+        return new Http\DataResponse();
276
+    }
277
+
278
+    /**
279
+     * @NoCSRFRequired
280
+     * @PublicPage
281
+     *
282
+     * decline server-to-server share
283
+     *
284
+     * @param int $id
285
+     * @return Http\DataResponse
286
+     * @throws OCSException
287
+     */
288
+    public function declineShare($id) {
289
+
290
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
291
+
292
+        $notification = [
293
+            'sharedSecret' => $token,
294
+            'message' => 'Recipient declined the share'
295
+        ];
296
+
297
+        try {
298
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
299
+            $provider->notificationReceived('SHARE_DECLINED', $id, $notification);
300
+        } catch (ProviderDoesNotExistsException $e) {
301
+            throw new OCSException('Server does not support federated cloud sharing', 503);
302
+        } catch (ShareNotFound $e) {
303
+            $this->logger->debug('Share not found: ' . $e->getMessage());
304
+        } catch (\Exception $e) {
305
+            $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
306
+        }
307
+
308
+        return new Http\DataResponse();
309
+    }
310
+
311
+    /**
312
+     * @NoCSRFRequired
313
+     * @PublicPage
314
+     *
315
+     * remove server-to-server share if it was unshared by the owner
316
+     *
317
+     * @param int $id
318
+     * @return Http\DataResponse
319
+     * @throws OCSException
320
+     */
321
+    public function unshare($id) {
322
+
323
+        if (!$this->isS2SEnabled()) {
324
+            throw new OCSException('Server does not support federated cloud sharing', 503);
325
+        }
326
+
327
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
328
+
329
+        try {
330
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
331
+            $notification = ['sharedSecret' => $token];
332
+            $provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
333
+        } catch (\Exception $e) {
334
+            $this->logger->debug('processing unshare notification failed: ' . $e->getMessage());
335
+        }
336
+
337
+        return new Http\DataResponse();
338
+    }
339
+
340
+    private function cleanupRemote($remote) {
341
+        $remote = substr($remote, strpos($remote, '://') + 3);
342
+
343
+        return rtrim($remote, '/');
344
+    }
345
+
346
+
347
+    /**
348
+     * @NoCSRFRequired
349
+     * @PublicPage
350
+     *
351
+     * federated share was revoked, either by the owner or the re-sharer
352
+     *
353
+     * @param int $id
354
+     * @return Http\DataResponse
355
+     * @throws OCSBadRequestException
356
+     */
357
+    public function revoke($id) {
358
+
359
+        $token = $this->request->getParam('token');
360
+
361
+        try {
362
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
363
+            $notification = ['sharedSecret' => $token];
364
+            $provider->notificationReceived('RESHARE_UNDO', $id, $notification);
365
+            return new Http\DataResponse();
366
+        } catch (\Exception $e) {
367
+            throw new OCSBadRequestException();
368
+        }
369
+
370
+    }
371
+
372
+    /**
373
+     * get share
374
+     *
375
+     * @param int $id
376
+     * @param string $token
377
+     * @return array|bool
378
+     */
379
+    protected function getShare($id, $token) {
380
+        $query = $this->connection->getQueryBuilder();
381
+        $query->select('*')->from($this->shareTable)
382
+            ->where($query->expr()->eq('token', $query->createNamedParameter($token)))
383
+            ->andWhere($query->expr()->eq('share_type', $query->createNamedParameter(FederatedShareProvider::SHARE_TYPE_REMOTE)))
384
+            ->andWhere($query->expr()->eq('id', $query->createNamedParameter($id)));
385
+
386
+        $result = $query->execute()->fetchAll();
387
+
388
+        if (!empty($result) && isset($result[0])) {
389
+            return $result[0];
390
+        }
391
+
392
+        return false;
393
+    }
394
+
395
+    /**
396
+     * check if server-to-server sharing is enabled
397
+     *
398
+     * @param bool $incoming
399
+     * @return bool
400
+     */
401
+    private function isS2SEnabled($incoming = false) {
402
+
403
+        $result = \OCP\App::isEnabled('files_sharing');
404
+
405
+        if ($incoming) {
406
+            $result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
407
+        } else {
408
+            $result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
409
+        }
410
+
411
+        return $result;
412
+    }
413
+
414
+    /**
415
+     * @NoCSRFRequired
416
+     * @PublicPage
417
+     *
418
+     * update share information to keep federated re-shares in sync
419
+     *
420
+     * @param int $id
421
+     * @return Http\DataResponse
422
+     * @throws OCSBadRequestException
423
+     */
424
+    public function updatePermissions($id) {
425
+        $token = $this->request->getParam('token', null);
426
+        $ncPermissions = $this->request->getParam('permissions', null);
427
+
428
+        try {
429
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
430
+            $ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
431
+            $notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
432
+            $provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
433
+        } catch (\Exception $e) {
434
+            $this->logger->debug($e->getMessage());
435
+            throw new OCSBadRequestException();
436
+        }
437
+
438
+        return new Http\DataResponse();
439
+    }
440
+
441
+    /**
442
+     * translate Nextcloud permissions to OCM Permissions
443
+     *
444
+     * @param $ncPermissions
445
+     * @return array
446
+     */
447
+    protected function ncPermissions2ocmPermissions($ncPermissions) {
448
+
449
+        $ocmPermissions = [];
450
+
451
+        if ($ncPermissions & Constants::PERMISSION_SHARE) {
452
+            $ocmPermissions[] = 'share';
453
+        }
454
+
455
+        if ($ncPermissions & Constants::PERMISSION_READ) {
456
+            $ocmPermissions[] = 'read';
457
+        }
458
+
459
+        if (($ncPermissions & Constants::PERMISSION_CREATE) ||
460
+            ($ncPermissions & Constants::PERMISSION_UPDATE)) {
461
+            $ocmPermissions[] = 'write';
462
+        }
463
+
464
+        return $ocmPermissions;
465
+
466
+    }
467
+
468
+    /**
469
+     * @NoCSRFRequired
470
+     * @PublicPage
471
+     *
472
+     * change the owner of a server-to-server share
473
+     *
474
+     * @param int $id
475
+     * @return Http\DataResponse
476
+     * @throws \InvalidArgumentException
477
+     * @throws OCSException
478
+     */
479
+    public function move($id) {
480
+
481
+        if (!$this->isS2SEnabled()) {
482
+            throw new OCSException('Server does not support federated cloud sharing', 503);
483
+        }
484
+
485
+        $token = $this->request->getParam('token');
486
+        $remote = $this->request->getParam('remote');
487
+        $newRemoteId = $this->request->getParam('remote_id', $id);
488
+        $cloudId = $this->cloudIdManager->resolveCloudId($remote);
489
+
490
+        $qb = $this->connection->getQueryBuilder();
491
+        $query = $qb->update('share_external')
492
+            ->set('remote', $qb->createNamedParameter($cloudId->getRemote()))
493
+            ->set('owner', $qb->createNamedParameter($cloudId->getUser()))
494
+            ->set('remote_id', $qb->createNamedParameter($newRemoteId))
495
+            ->where($qb->expr()->eq('remote_id', $qb->createNamedParameter($id)))
496
+            ->andWhere($qb->expr()->eq('share_token', $qb->createNamedParameter($token)));
497
+        $affected = $query->execute();
498
+
499
+        if ($affected > 0) {
500
+            return new Http\DataResponse(['remote' => $cloudId->getRemote(), 'owner' => $cloudId->getUser()]);
501
+        } else {
502
+            throw new OCSBadRequestException('Share not found or token invalid');
503
+        }
504
+    }
505 505
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
 		$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
146 146
 		$sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
147 147
 		$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
148
-		$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
148
+		$remoteId = isset($_POST['remoteId']) ? (int) $_POST['remoteId'] : null;
149 149
 		$sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
150 150
 		$ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
151 151
 
@@ -180,7 +180,7 @@  discard block
 block discarded – undo
180 180
 		} catch (ProviderCouldNotAddShareException $e) {
181 181
 			throw new OCSException($e->getMessage(), $e->getCode());
182 182
 		} catch (\Exception $e) {
183
-			throw new OCSException('internal server error, was not able to add share from ' . $remote, 500);
183
+			throw new OCSException('internal server error, was not able to add share from '.$remote, 500);
184 184
 		}
185 185
 
186 186
 		return new Http\DataResponse();
@@ -202,8 +202,8 @@  discard block
 block discarded – undo
202 202
 
203 203
 		$token = $this->request->getParam('token', null);
204 204
 		$shareWith = $this->request->getParam('shareWith', null);
205
-		$permission = (int)$this->request->getParam('permission', null);
206
-		$remoteId = (int)$this->request->getParam('remoteId', null);
205
+		$permission = (int) $this->request->getParam('permission', null);
206
+		$remoteId = (int) $this->request->getParam('remoteId', null);
207 207
 
208 208
 		if ($id === null ||
209 209
 			$token === null ||
@@ -231,9 +231,9 @@  discard block
 block discarded – undo
231 231
 		} catch (ProviderDoesNotExistsException $e) {
232 232
 			throw new OCSException('Server does not support federated cloud sharing', 503);
233 233
 		} catch (ShareNotFound $e) {
234
-			$this->logger->debug('Share not found: ' . $e->getMessage());
234
+			$this->logger->debug('Share not found: '.$e->getMessage());
235 235
 		} catch (\Exception $e) {
236
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
236
+			$this->logger->debug('internal server error, can not process notification: '.$e->getMessage());
237 237
 		}
238 238
 
239 239
 		throw new OCSBadRequestException();
@@ -267,9 +267,9 @@  discard block
 block discarded – undo
267 267
 		} catch (ProviderDoesNotExistsException $e) {
268 268
 			throw new OCSException('Server does not support federated cloud sharing', 503);
269 269
 		} catch (ShareNotFound $e) {
270
-			$this->logger->debug('Share not found: ' . $e->getMessage());
270
+			$this->logger->debug('Share not found: '.$e->getMessage());
271 271
 		} catch (\Exception $e) {
272
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
272
+			$this->logger->debug('internal server error, can not process notification: '.$e->getMessage());
273 273
 		}
274 274
 
275 275
 		return new Http\DataResponse();
@@ -300,9 +300,9 @@  discard block
 block discarded – undo
300 300
 		} catch (ProviderDoesNotExistsException $e) {
301 301
 			throw new OCSException('Server does not support federated cloud sharing', 503);
302 302
 		} catch (ShareNotFound $e) {
303
-			$this->logger->debug('Share not found: ' . $e->getMessage());
303
+			$this->logger->debug('Share not found: '.$e->getMessage());
304 304
 		} catch (\Exception $e) {
305
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
305
+			$this->logger->debug('internal server error, can not process notification: '.$e->getMessage());
306 306
 		}
307 307
 
308 308
 		return new Http\DataResponse();
@@ -331,7 +331,7 @@  discard block
 block discarded – undo
331 331
 			$notification = ['sharedSecret' => $token];
332 332
 			$provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
333 333
 		} catch (\Exception $e) {
334
-			$this->logger->debug('processing unshare notification failed: ' . $e->getMessage());
334
+			$this->logger->debug('processing unshare notification failed: '.$e->getMessage());
335 335
 		}
336 336
 
337 337
 		return new Http\DataResponse();
@@ -427,7 +427,7 @@  discard block
 block discarded – undo
427 427
 
428 428
 		try {
429 429
 			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
430
-			$ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
430
+			$ocmPermissions = $this->ncPermissions2ocmPermissions((int) $ncPermissions);
431 431
 			$notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
432 432
 			$provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
433 433
 		} catch (\Exception $e) {
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
 	 * share received from another server
143 143
 	 *
144 144
 	 * @param ICloudFederationShare $share
145
-	 * @return string provider specific unique ID of the share
145
+	 * @return integer provider specific unique ID of the share
146 146
 	 *
147 147
 	 * @throws ProviderCouldNotAddShareException
148 148
 	 * @throws \OCP\AppFramework\QueryException
@@ -550,7 +550,7 @@  discard block
 block discarded – undo
550 550
 	/**
551 551
 	 * recipient of a share request to re-share the file with another user
552 552
 	 *
553
-	 * @param $id
553
+	 * @param string $id
554 554
 	 * @param $notification
555 555
 	 * @return array
556 556
 	 * @throws AuthenticationFailedException
Please login to merge, or discard this patch.
Indentation   +710 added lines, -710 removed lines patch added patch discarded remove patch
@@ -50,716 +50,716 @@
 block discarded – undo
50 50
 
51 51
 class CloudFederationProviderFiles implements ICloudFederationProvider {
52 52
 
53
-	/** @var IAppManager */
54
-	private $appManager;
55
-
56
-	/** @var FederatedShareProvider */
57
-	private $federatedShareProvider;
58
-
59
-	/** @var AddressHandler */
60
-	private $addressHandler;
61
-
62
-	/** @var ILogger */
63
-	private $logger;
64
-
65
-	/** @var IUserManager */
66
-	private $userManager;
67
-
68
-	/** @var ICloudIdManager */
69
-	private $cloudIdManager;
70
-
71
-	/** @var IActivityManager */
72
-	private $activityManager;
73
-
74
-	/** @var INotificationManager */
75
-	private $notificationManager;
76
-
77
-	/** @var IURLGenerator */
78
-	private $urlGenerator;
79
-
80
-	/** @var ICloudFederationFactory */
81
-	private $cloudFederationFactory;
82
-
83
-	/** @var ICloudFederationProviderManager */
84
-	private $cloudFederationProviderManager;
85
-
86
-	/** @var IDBConnection */
87
-	private $connection;
88
-
89
-	/**
90
-	 * CloudFederationProvider constructor.
91
-	 *
92
-	 * @param IAppManager $appManager
93
-	 * @param FederatedShareProvider $federatedShareProvider
94
-	 * @param AddressHandler $addressHandler
95
-	 * @param ILogger $logger
96
-	 * @param IUserManager $userManager
97
-	 * @param ICloudIdManager $cloudIdManager
98
-	 * @param IActivityManager $activityManager
99
-	 * @param INotificationManager $notificationManager
100
-	 * @param IURLGenerator $urlGenerator
101
-	 * @param ICloudFederationFactory $cloudFederationFactory
102
-	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
103
-	 * @param IDBConnection $connection
104
-	 */
105
-	public function __construct(IAppManager $appManager,
106
-								FederatedShareProvider $federatedShareProvider,
107
-								AddressHandler $addressHandler,
108
-								ILogger $logger,
109
-								IUserManager $userManager,
110
-								ICloudIdManager $cloudIdManager,
111
-								IActivityManager $activityManager,
112
-								INotificationManager $notificationManager,
113
-								IURLGenerator $urlGenerator,
114
-								ICloudFederationFactory $cloudFederationFactory,
115
-								ICloudFederationProviderManager $cloudFederationProviderManager,
116
-								IDBConnection $connection
117
-	) {
118
-		$this->appManager = $appManager;
119
-		$this->federatedShareProvider = $federatedShareProvider;
120
-		$this->addressHandler = $addressHandler;
121
-		$this->logger = $logger;
122
-		$this->userManager = $userManager;
123
-		$this->cloudIdManager = $cloudIdManager;
124
-		$this->activityManager = $activityManager;
125
-		$this->notificationManager = $notificationManager;
126
-		$this->urlGenerator = $urlGenerator;
127
-		$this->cloudFederationFactory = $cloudFederationFactory;
128
-		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
129
-		$this->connection = $connection;
130
-	}
131
-
132
-
133
-
134
-	/**
135
-	 * @return string
136
-	 */
137
-	public function getShareType() {
138
-		return 'file';
139
-	}
140
-
141
-	/**
142
-	 * share received from another server
143
-	 *
144
-	 * @param ICloudFederationShare $share
145
-	 * @return string provider specific unique ID of the share
146
-	 *
147
-	 * @throws ProviderCouldNotAddShareException
148
-	 * @throws \OCP\AppFramework\QueryException
149
-	 * @throws \OC\HintException
150
-	 * @since 14.0.0
151
-	 */
152
-	public function shareReceived(ICloudFederationShare $share) {
153
-
154
-		if (!$this->isS2SEnabled(true)) {
155
-			throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
156
-		}
157
-
158
-		$protocol = $share->getProtocol();
159
-		if ($protocol['name'] !== 'webdav') {
160
-			throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
161
-		}
162
-
163
-		list($ownerUid, $remote) = $this->addressHandler->splitUserRemote($share->getOwner());
164
-
165
-		$remote = $remote;
166
-		$token = $share->getShareSecret();
167
-		$name = $share->getResourceName();
168
-		$owner = $share->getOwnerDisplayName();
169
-		$sharedBy = $share->getSharedByDisplayName();
170
-		$shareWith = $share->getShareWith();
171
-		$remoteId = $share->getProviderId();
172
-		$sharedByFederatedId = $share->getSharedBy();
173
-		$ownerFederatedId = $share->getOwner();
174
-
175
-		// if no explicit information about the person who created the share was send
176
-		// we assume that the share comes from the owner
177
-		if ($sharedByFederatedId === null) {
178
-			$sharedBy = $owner;
179
-			$sharedByFederatedId = $ownerFederatedId;
180
-		}
181
-
182
-		if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
183
-
184
-			if (!Util::isValidFileName($name)) {
185
-				throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
186
-			}
187
-
188
-			// FIXME this should be a method in the user management instead
189
-			$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
190
-			Util::emitHook(
191
-				'\OCA\Files_Sharing\API\Server2Server',
192
-				'preLoginNameUsedAsUserName',
193
-				array('uid' => &$shareWith)
194
-			);
195
-			$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
196
-
197
-			if (!$this->userManager->userExists($shareWith)) {
198
-				throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
199
-			}
200
-
201
-			\OC_Util::setupFS($shareWith);
202
-
203
-			$externalManager = new \OCA\Files_Sharing\External\Manager(
204
-				\OC::$server->getDatabaseConnection(),
205
-				Filesystem::getMountManager(),
206
-				Filesystem::getLoader(),
207
-				\OC::$server->getHTTPClientService(),
208
-				\OC::$server->getNotificationManager(),
209
-				\OC::$server->query(\OCP\OCS\IDiscoveryService::class),
210
-				\OC::$server->getCloudFederationProviderManager(),
211
-				\OC::$server->getCloudFederationFactory(),
212
-				$shareWith
213
-			);
214
-
215
-			try {
216
-				$externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
217
-				$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
218
-
219
-				$event = $this->activityManager->generateEvent();
220
-				$event->setApp('files_sharing')
221
-					->setType('remote_share')
222
-					->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
223
-					->setAffectedUser($shareWith)
224
-					->setObject('remote_share', (int)$shareId, $name);
225
-				\OC::$server->getActivityManager()->publish($event);
226
-
227
-				$notification = $this->notificationManager->createNotification();
228
-				$notification->setApp('files_sharing')
229
-					->setUser($shareWith)
230
-					->setDateTime(new \DateTime())
231
-					->setObject('remote_share', $shareId)
232
-					->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/')]);
233
-
234
-				$declineAction = $notification->createAction();
235
-				$declineAction->setLabel('decline')
236
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
237
-				$notification->addAction($declineAction);
238
-
239
-				$acceptAction = $notification->createAction();
240
-				$acceptAction->setLabel('accept')
241
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
242
-				$notification->addAction($acceptAction);
243
-
244
-				$this->notificationManager->notify($notification);
245
-
246
-				return $shareId;
247
-			} catch (\Exception $e) {
248
-				$this->logger->logException($e, [
249
-					'message' => 'Server can not add remote share.',
250
-					'level' => Util::ERROR,
251
-					'app' => 'files_sharing'
252
-				]);
253
-				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
254
-			}
255
-		}
256
-
257
-		throw new ProviderCouldNotAddShareException('server can not add remote share, missing parameter', '', HTTP::STATUS_BAD_REQUEST);
258
-
259
-	}
260
-
261
-	/**
262
-	 * notification received from another server
263
-	 *
264
-	 * @param string $notificationType (e.g. SHARE_ACCEPTED)
265
-	 * @param string $providerId id of the share
266
-	 * @param array $notification payload of the notification
267
-	 * @return array data send back to the sender
268
-	 *
269
-	 * @throws ActionNotSupportedException
270
-	 * @throws AuthenticationFailedException
271
-	 * @throws BadRequestException
272
-	 * @throws \OC\HintException
273
-	 * @since 14.0.0
274
-	 */
275
-	public function notificationReceived($notificationType, $providerId, array $notification) {
276
-
277
-		switch ($notificationType) {
278
-			case 'SHARE_ACCEPTED':
279
-				return $this->shareAccepted($providerId, $notification);
280
-			case 'SHARE_DECLINED':
281
-				return $this->shareDeclined($providerId, $notification);
282
-			case 'SHARE_UNSHARED':
283
-				return $this->unshare($providerId, $notification);
284
-			case 'REQUEST_RESHARE':
285
-				return $this->reshareRequested($providerId, $notification);
286
-			case 'RESHARE_UNDO':
287
-				return $this->undoReshare($providerId, $notification);
288
-			case 'RESHARE_CHANGE_PERMISSION':
289
-				return $this->updateResharePermissions($providerId, $notification);
290
-		}
291
-
292
-
293
-		throw new BadRequestException([$notificationType]);
294
-	}
295
-
296
-	/**
297
-	 * process notification that the recipient accepted a share
298
-	 *
299
-	 * @param string $id
300
-	 * @param array $notification
301
-	 * @return array
302
-	 * @throws ActionNotSupportedException
303
-	 * @throws AuthenticationFailedException
304
-	 * @throws BadRequestException
305
-	 * @throws \OC\HintException
306
-	 */
307
-	private function shareAccepted($id, $notification) {
308
-
309
-		if (!$this->isS2SEnabled()) {
310
-			throw new ActionNotSupportedException('Server does not support federated cloud sharing');
311
-		}
312
-
313
-		if (!isset($notification['sharedSecret'])) {
314
-			throw new BadRequestException(['sharedSecret']);
315
-		}
316
-
317
-		$token = $notification['sharedSecret'];
318
-
319
-		$share = $this->federatedShareProvider->getShareById($id);
320
-
321
-		$this->verifyShare($share, $token);
322
-		$this->executeAcceptShare($share);
323
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
324
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
325
-			$remoteId = $this->federatedShareProvider->getRemoteId($share);
326
-			$notification = $this->cloudFederationFactory->getCloudFederationNotification();
327
-			$notification->setMessage(
328
-				'SHARE_ACCEPTED',
329
-				'file',
330
-				$remoteId,
331
-				[
332
-					'sharedSecret' => $token,
333
-					'message' => 'Recipient accepted the re-share'
334
-				]
335
-
336
-			);
337
-			$this->cloudFederationProviderManager->sendNotification($remote, $notification);
338
-
339
-		}
340
-
341
-		return [];
342
-	}
343
-
344
-	/**
345
-	 * @param IShare $share
346
-	 * @throws ShareNotFound
347
-	 */
348
-	protected function executeAcceptShare(IShare $share) {
349
-		try {
350
-			$fileId = (int)$share->getNode()->getId();
351
-			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
352
-		} catch (\Exception $e) {
353
-			throw new ShareNotFound();
354
-		}
355
-
356
-		$event = $this->activityManager->generateEvent();
357
-		$event->setApp('files_sharing')
358
-			->setType('remote_share')
359
-			->setAffectedUser($this->getCorrectUid($share))
360
-			->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), [$fileId => $file]])
361
-			->setObject('files', $fileId, $file)
362
-			->setLink($link);
363
-		$this->activityManager->publish($event);
364
-	}
365
-
366
-	/**
367
-	 * process notification that the recipient declined a share
368
-	 *
369
-	 * @param string $id
370
-	 * @param array $notification
371
-	 * @return array
372
-	 * @throws ActionNotSupportedException
373
-	 * @throws AuthenticationFailedException
374
-	 * @throws BadRequestException
375
-	 * @throws ShareNotFound
376
-	 * @throws \OC\HintException
377
-	 *
378
-	 */
379
-	protected function shareDeclined($id, $notification) {
380
-
381
-		if (!$this->isS2SEnabled()) {
382
-			throw new ActionNotSupportedException('Server does not support federated cloud sharing');
383
-		}
384
-
385
-		if (!isset($notification['sharedSecret'])) {
386
-			throw new BadRequestException(['sharedSecret']);
387
-		}
388
-
389
-		$token = $notification['sharedSecret'];
390
-
391
-		$share = $this->federatedShareProvider->getShareById($id);
392
-
393
-		$this->verifyShare($share, $token);
394
-
395
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
396
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
397
-			$remoteId = $this->federatedShareProvider->getRemoteId($share);
398
-			$notification = $this->cloudFederationFactory->getCloudFederationNotification();
399
-			$notification->setMessage(
400
-				'SHARE_DECLINED',
401
-				'file',
402
-				$remoteId,
403
-				[
404
-					'sharedSecret' => $token,
405
-					'message' => 'Recipient declined the re-share'
406
-				]
407
-
408
-			);
409
-			$this->cloudFederationProviderManager->sendNotification($remote, $notification);
410
-		}
411
-
412
-		$this->executeDeclineShare($share);
413
-
414
-		return [];
415
-
416
-	}
417
-
418
-	/**
419
-	 * delete declined share and create a activity
420
-	 *
421
-	 * @param IShare $share
422
-	 * @throws ShareNotFound
423
-	 */
424
-	protected function executeDeclineShare(IShare $share) {
425
-		$this->federatedShareProvider->removeShareFromTable($share);
426
-
427
-		try {
428
-			$fileId = (int)$share->getNode()->getId();
429
-			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
430
-		} catch (\Exception $e) {
431
-			throw new ShareNotFound();
432
-		}
433
-
434
-		$event = $this->activityManager->generateEvent();
435
-		$event->setApp('files_sharing')
436
-			->setType('remote_share')
437
-			->setAffectedUser($this->getCorrectUid($share))
438
-			->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]])
439
-			->setObject('files', $fileId, $file)
440
-			->setLink($link);
441
-		$this->activityManager->publish($event);
442
-
443
-	}
444
-
445
-	/**
446
-	 * received the notification that the owner unshared a file from you
447
-	 *
448
-	 * @param string $id
449
-	 * @param string $notification
450
-	 * @return array
451
-	 * @throws AuthenticationFailedException
452
-	 * @throws BadRequestException
453
-	 */
454
-	private function undoReshare($id, $notification) {
455
-		if (!isset($notification['sharedSecret'])) {
456
-			throw new BadRequestException(['sharedSecret']);
457
-		}
458
-		$token = $notification['sharedSecret'];
459
-
460
-		$share = $this->federatedShareProvider->getShareById($id);
461
-
462
-		$this->verifyShare($share, $token);
463
-		$this->federatedShareProvider->removeShareFromTable($share);
464
-		return [];
465
-	}
466
-
467
-	/**
468
-	 * unshare file from self
469
-	 *
470
-	 * @param string $id
471
-	 * @param array $notification
472
-	 * @return array
473
-	 * @throws ActionNotSupportedException
474
-	 * @throws BadRequestException
475
-	 */
476
-	private function unshare($id, array $notification) {
477
-
478
-		if (!$this->isS2SEnabled(true)) {
479
-			throw new ActionNotSupportedException("incoming shares disabled!");
480
-		}
481
-
482
-		if (!isset($notification['sharedSecret'])) {
483
-			throw new BadRequestException(['sharedSecret']);
484
-		}
485
-		$token = $notification['sharedSecret'];
486
-
487
-		$qb = $this->connection->getQueryBuilder();
488
-		$qb->select('*')
489
-			->from('share_external')
490
-			->where(
491
-				$qb->expr()->andX(
492
-					$qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
493
-					$qb->expr()->eq('share_token', $qb->createNamedParameter($token))
494
-				)
495
-			);
496
-
497
-		$result = $qb->execute();
498
-		$share = $result->fetch();
499
-		$result->closeCursor();
500
-
501
-		if ($token && $id && !empty($share)) {
502
-
503
-			$remote = $this->cleanupRemote($share['remote']);
504
-
505
-			$owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
506
-			$mountpoint = $share['mountpoint'];
507
-			$user = $share['user'];
508
-
509
-			$qb = $this->connection->getQueryBuilder();
510
-			$qb->delete('share_external')
511
-				->where(
512
-					$qb->expr()->andX(
513
-						$qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
514
-						$qb->expr()->eq('share_token', $qb->createNamedParameter($token))
515
-					)
516
-				);
517
-
518
-			$qb->execute();
519
-
520
-			if ($share['accepted']) {
521
-				$path = trim($mountpoint, '/');
522
-			} else {
523
-				$path = trim($share['name'], '/');
524
-			}
525
-
526
-			$notification = $this->notificationManager->createNotification();
527
-			$notification->setApp('files_sharing')
528
-				->setUser($share['user'])
529
-				->setObject('remote_share', (int)$share['id']);
530
-			$this->notificationManager->markProcessed($notification);
531
-
532
-			$event = $this->activityManager->generateEvent();
533
-			$event->setApp('files_sharing')
534
-				->setType('remote_share')
535
-				->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
536
-				->setAffectedUser($user)
537
-				->setObject('remote_share', (int)$share['id'], $path);
538
-			\OC::$server->getActivityManager()->publish($event);
539
-		}
540
-
541
-		return [];
542
-	}
543
-
544
-	private function cleanupRemote($remote) {
545
-		$remote = substr($remote, strpos($remote, '://') + 3);
546
-
547
-		return rtrim($remote, '/');
548
-	}
549
-
550
-	/**
551
-	 * recipient of a share request to re-share the file with another user
552
-	 *
553
-	 * @param $id
554
-	 * @param $notification
555
-	 * @return array
556
-	 * @throws AuthenticationFailedException
557
-	 * @throws BadRequestException
558
-	 * @throws ProviderCouldNotAddShareException
559
-	 * @throws ShareNotFound
560
-	 */
561
-	protected function reshareRequested($id, $notification) {
562
-
563
-		if (!isset($notification['sharedSecret'])) {
564
-			throw new BadRequestException(['sharedSecret']);
565
-		}
566
-		$token = $notification['sharedSecret'];
567
-
568
-		if (!isset($notification['shareWith'])) {
569
-			throw new BadRequestException(['shareWith']);
570
-		}
571
-		$shareWith = $notification['shareWith'];
572
-
573
-		if (!isset($notification['senderId'])) {
574
-			throw new BadRequestException(['senderId']);
575
-		}
576
-		$senderId = $notification['senderId'];
577
-
578
-		$share = $this->federatedShareProvider->getShareById($id);
579
-		// don't allow to share a file back to the owner
580
-		try {
581
-			list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
582
-			$owner = $share->getShareOwner();
583
-			$currentServer = $this->addressHandler->generateRemoteURL();
584
-			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
585
-				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
586
-			}
587
-		} catch (\Exception $e) {
588
-			throw new ProviderCouldNotAddShareException($e->getMessage());
589
-		}
590
-
591
-		$this->verifyShare($share, $token);
592
-
593
-		// check if re-sharing is allowed
594
-		if ($share->getPermissions() & Constants::PERMISSION_SHARE) {
595
-			// the recipient of the initial share is now the initiator for the re-share
596
-			$share->setSharedBy($share->getSharedWith());
597
-			$share->setSharedWith($shareWith);
598
-			$result = $this->federatedShareProvider->create($share);
599
-			$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
600
-			return ['token' => $result->getToken(), 'providerId' => $result->getId()];
601
-		} else {
602
-			throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
603
-		}
604
-
605
-		throw new BadRequestException([]);
606
-	}
607
-
608
-	/**
609
-	 * update permission of a re-share so that the share dialog shows the right
610
-	 * permission if the owner or the sender changes the permission
611
-	 *
612
-	 * @param string $id
613
-	 * @param array $notification
614
-	 * @return array
615
-	 * @throws AuthenticationFailedException
616
-	 * @throws BadRequestException
617
-	 */
618
-	protected function updateResharePermissions($id, $notification) {
619
-
620
-		if (!isset($notification['sharedSecret'])) {
621
-			throw new BadRequestException(['sharedSecret']);
622
-		}
623
-		$token = $notification['sharedSecret'];
624
-
625
-		if (!isset($notification['permission'])) {
626
-			throw new BadRequestException(['permission']);
627
-		}
628
-		$ocmPermissions = $notification['permission'];
629
-
630
-		$share = $this->federatedShareProvider->getShareById($id);
631
-
632
-		$ncPermission = $this->ocmPermissions2ncPermissions($ocmPermissions);
633
-
634
-		$this->verifyShare($share, $token);
635
-		$this->updatePermissionsInDatabase($share, $ncPermission);
636
-
637
-		return [];
638
-	}
639
-
640
-	/**
641
-	 * translate OCM Permissions to Nextcloud permissions
642
-	 *
643
-	 * @param $ocmPermissions
644
-	 * @return int
645
-	 * @throws BadRequestException
646
-	 */
647
-	protected function ocmPermissions2ncPermissions($ocmPermissions) {
648
-		error_log("ocm permissions: " . json_encode($ocmPermissions));
649
-		$ncPermissions = 0;
650
-		foreach($ocmPermissions as $permission) {
651
-			switch (strtolower($permission)) {
652
-				case 'read':
653
-					$ncPermissions += Constants::PERMISSION_READ;
654
-					break;
655
-				case 'write':
656
-					$ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
657
-					break;
658
-				case 'share':
659
-					$ncPermissions += Constants::PERMISSION_SHARE;
660
-					break;
661
-				default:
662
-					throw new BadRequestException(['permission']);
663
-			}
664
-
665
-			error_log("new permissions: " . $ncPermissions);
666
-		}
667
-
668
-		return $ncPermissions;
669
-	}
670
-
671
-	/**
672
-	 * update permissions in database
673
-	 *
674
-	 * @param IShare $share
675
-	 * @param int $permissions
676
-	 */
677
-	protected function updatePermissionsInDatabase(IShare $share, $permissions) {
678
-		$query = $this->connection->getQueryBuilder();
679
-		$query->update('share')
680
-			->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
681
-			->set('permissions', $query->createNamedParameter($permissions))
682
-			->execute();
683
-	}
684
-
685
-
686
-	/**
687
-	 * get file
688
-	 *
689
-	 * @param string $user
690
-	 * @param int $fileSource
691
-	 * @return array with internal path of the file and a absolute link to it
692
-	 */
693
-	private function getFile($user, $fileSource) {
694
-		\OC_Util::setupFS($user);
695
-
696
-		try {
697
-			$file = Filesystem::getPath($fileSource);
698
-		} catch (NotFoundException $e) {
699
-			$file = null;
700
-		}
701
-		$args = Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
702
-		$link = Util::linkToAbsolute('files', 'index.php', $args);
703
-
704
-		return array($file, $link);
705
-
706
-	}
707
-
708
-	/**
709
-	 * check if we are the initiator or the owner of a re-share and return the correct UID
710
-	 *
711
-	 * @param IShare $share
712
-	 * @return string
713
-	 */
714
-	protected function getCorrectUid(IShare $share) {
715
-		if ($this->userManager->userExists($share->getShareOwner())) {
716
-			return $share->getShareOwner();
717
-		}
718
-
719
-		return $share->getSharedBy();
720
-	}
721
-
722
-
723
-
724
-	/**
725
-	 * check if we got the right share
726
-	 *
727
-	 * @param IShare $share
728
-	 * @param string $token
729
-	 * @return bool
730
-	 * @throws AuthenticationFailedException
731
-	 */
732
-	protected function verifyShare(IShare $share, $token) {
733
-		if (
734
-			$share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
735
-			$share->getToken() === $token
736
-		) {
737
-			return true;
738
-		}
739
-
740
-		throw new AuthenticationFailedException();
741
-	}
742
-
743
-
744
-
745
-	/**
746
-	 * check if server-to-server sharing is enabled
747
-	 *
748
-	 * @param bool $incoming
749
-	 * @return bool
750
-	 */
751
-	private function isS2SEnabled($incoming = false) {
752
-
753
-		$result = $this->appManager->isEnabledForUser('files_sharing');
754
-
755
-		if ($incoming) {
756
-			$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
757
-		} else {
758
-			$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
759
-		}
760
-
761
-		return $result;
762
-	}
53
+    /** @var IAppManager */
54
+    private $appManager;
55
+
56
+    /** @var FederatedShareProvider */
57
+    private $federatedShareProvider;
58
+
59
+    /** @var AddressHandler */
60
+    private $addressHandler;
61
+
62
+    /** @var ILogger */
63
+    private $logger;
64
+
65
+    /** @var IUserManager */
66
+    private $userManager;
67
+
68
+    /** @var ICloudIdManager */
69
+    private $cloudIdManager;
70
+
71
+    /** @var IActivityManager */
72
+    private $activityManager;
73
+
74
+    /** @var INotificationManager */
75
+    private $notificationManager;
76
+
77
+    /** @var IURLGenerator */
78
+    private $urlGenerator;
79
+
80
+    /** @var ICloudFederationFactory */
81
+    private $cloudFederationFactory;
82
+
83
+    /** @var ICloudFederationProviderManager */
84
+    private $cloudFederationProviderManager;
85
+
86
+    /** @var IDBConnection */
87
+    private $connection;
88
+
89
+    /**
90
+     * CloudFederationProvider constructor.
91
+     *
92
+     * @param IAppManager $appManager
93
+     * @param FederatedShareProvider $federatedShareProvider
94
+     * @param AddressHandler $addressHandler
95
+     * @param ILogger $logger
96
+     * @param IUserManager $userManager
97
+     * @param ICloudIdManager $cloudIdManager
98
+     * @param IActivityManager $activityManager
99
+     * @param INotificationManager $notificationManager
100
+     * @param IURLGenerator $urlGenerator
101
+     * @param ICloudFederationFactory $cloudFederationFactory
102
+     * @param ICloudFederationProviderManager $cloudFederationProviderManager
103
+     * @param IDBConnection $connection
104
+     */
105
+    public function __construct(IAppManager $appManager,
106
+                                FederatedShareProvider $federatedShareProvider,
107
+                                AddressHandler $addressHandler,
108
+                                ILogger $logger,
109
+                                IUserManager $userManager,
110
+                                ICloudIdManager $cloudIdManager,
111
+                                IActivityManager $activityManager,
112
+                                INotificationManager $notificationManager,
113
+                                IURLGenerator $urlGenerator,
114
+                                ICloudFederationFactory $cloudFederationFactory,
115
+                                ICloudFederationProviderManager $cloudFederationProviderManager,
116
+                                IDBConnection $connection
117
+    ) {
118
+        $this->appManager = $appManager;
119
+        $this->federatedShareProvider = $federatedShareProvider;
120
+        $this->addressHandler = $addressHandler;
121
+        $this->logger = $logger;
122
+        $this->userManager = $userManager;
123
+        $this->cloudIdManager = $cloudIdManager;
124
+        $this->activityManager = $activityManager;
125
+        $this->notificationManager = $notificationManager;
126
+        $this->urlGenerator = $urlGenerator;
127
+        $this->cloudFederationFactory = $cloudFederationFactory;
128
+        $this->cloudFederationProviderManager = $cloudFederationProviderManager;
129
+        $this->connection = $connection;
130
+    }
131
+
132
+
133
+
134
+    /**
135
+     * @return string
136
+     */
137
+    public function getShareType() {
138
+        return 'file';
139
+    }
140
+
141
+    /**
142
+     * share received from another server
143
+     *
144
+     * @param ICloudFederationShare $share
145
+     * @return string provider specific unique ID of the share
146
+     *
147
+     * @throws ProviderCouldNotAddShareException
148
+     * @throws \OCP\AppFramework\QueryException
149
+     * @throws \OC\HintException
150
+     * @since 14.0.0
151
+     */
152
+    public function shareReceived(ICloudFederationShare $share) {
153
+
154
+        if (!$this->isS2SEnabled(true)) {
155
+            throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
156
+        }
157
+
158
+        $protocol = $share->getProtocol();
159
+        if ($protocol['name'] !== 'webdav') {
160
+            throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
161
+        }
162
+
163
+        list($ownerUid, $remote) = $this->addressHandler->splitUserRemote($share->getOwner());
164
+
165
+        $remote = $remote;
166
+        $token = $share->getShareSecret();
167
+        $name = $share->getResourceName();
168
+        $owner = $share->getOwnerDisplayName();
169
+        $sharedBy = $share->getSharedByDisplayName();
170
+        $shareWith = $share->getShareWith();
171
+        $remoteId = $share->getProviderId();
172
+        $sharedByFederatedId = $share->getSharedBy();
173
+        $ownerFederatedId = $share->getOwner();
174
+
175
+        // if no explicit information about the person who created the share was send
176
+        // we assume that the share comes from the owner
177
+        if ($sharedByFederatedId === null) {
178
+            $sharedBy = $owner;
179
+            $sharedByFederatedId = $ownerFederatedId;
180
+        }
181
+
182
+        if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
183
+
184
+            if (!Util::isValidFileName($name)) {
185
+                throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
186
+            }
187
+
188
+            // FIXME this should be a method in the user management instead
189
+            $this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
190
+            Util::emitHook(
191
+                '\OCA\Files_Sharing\API\Server2Server',
192
+                'preLoginNameUsedAsUserName',
193
+                array('uid' => &$shareWith)
194
+            );
195
+            $this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
196
+
197
+            if (!$this->userManager->userExists($shareWith)) {
198
+                throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
199
+            }
200
+
201
+            \OC_Util::setupFS($shareWith);
202
+
203
+            $externalManager = new \OCA\Files_Sharing\External\Manager(
204
+                \OC::$server->getDatabaseConnection(),
205
+                Filesystem::getMountManager(),
206
+                Filesystem::getLoader(),
207
+                \OC::$server->getHTTPClientService(),
208
+                \OC::$server->getNotificationManager(),
209
+                \OC::$server->query(\OCP\OCS\IDiscoveryService::class),
210
+                \OC::$server->getCloudFederationProviderManager(),
211
+                \OC::$server->getCloudFederationFactory(),
212
+                $shareWith
213
+            );
214
+
215
+            try {
216
+                $externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
217
+                $shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
218
+
219
+                $event = $this->activityManager->generateEvent();
220
+                $event->setApp('files_sharing')
221
+                    ->setType('remote_share')
222
+                    ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
223
+                    ->setAffectedUser($shareWith)
224
+                    ->setObject('remote_share', (int)$shareId, $name);
225
+                \OC::$server->getActivityManager()->publish($event);
226
+
227
+                $notification = $this->notificationManager->createNotification();
228
+                $notification->setApp('files_sharing')
229
+                    ->setUser($shareWith)
230
+                    ->setDateTime(new \DateTime())
231
+                    ->setObject('remote_share', $shareId)
232
+                    ->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/')]);
233
+
234
+                $declineAction = $notification->createAction();
235
+                $declineAction->setLabel('decline')
236
+                    ->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
237
+                $notification->addAction($declineAction);
238
+
239
+                $acceptAction = $notification->createAction();
240
+                $acceptAction->setLabel('accept')
241
+                    ->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
242
+                $notification->addAction($acceptAction);
243
+
244
+                $this->notificationManager->notify($notification);
245
+
246
+                return $shareId;
247
+            } catch (\Exception $e) {
248
+                $this->logger->logException($e, [
249
+                    'message' => 'Server can not add remote share.',
250
+                    'level' => Util::ERROR,
251
+                    'app' => 'files_sharing'
252
+                ]);
253
+                throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
254
+            }
255
+        }
256
+
257
+        throw new ProviderCouldNotAddShareException('server can not add remote share, missing parameter', '', HTTP::STATUS_BAD_REQUEST);
258
+
259
+    }
260
+
261
+    /**
262
+     * notification received from another server
263
+     *
264
+     * @param string $notificationType (e.g. SHARE_ACCEPTED)
265
+     * @param string $providerId id of the share
266
+     * @param array $notification payload of the notification
267
+     * @return array data send back to the sender
268
+     *
269
+     * @throws ActionNotSupportedException
270
+     * @throws AuthenticationFailedException
271
+     * @throws BadRequestException
272
+     * @throws \OC\HintException
273
+     * @since 14.0.0
274
+     */
275
+    public function notificationReceived($notificationType, $providerId, array $notification) {
276
+
277
+        switch ($notificationType) {
278
+            case 'SHARE_ACCEPTED':
279
+                return $this->shareAccepted($providerId, $notification);
280
+            case 'SHARE_DECLINED':
281
+                return $this->shareDeclined($providerId, $notification);
282
+            case 'SHARE_UNSHARED':
283
+                return $this->unshare($providerId, $notification);
284
+            case 'REQUEST_RESHARE':
285
+                return $this->reshareRequested($providerId, $notification);
286
+            case 'RESHARE_UNDO':
287
+                return $this->undoReshare($providerId, $notification);
288
+            case 'RESHARE_CHANGE_PERMISSION':
289
+                return $this->updateResharePermissions($providerId, $notification);
290
+        }
291
+
292
+
293
+        throw new BadRequestException([$notificationType]);
294
+    }
295
+
296
+    /**
297
+     * process notification that the recipient accepted a share
298
+     *
299
+     * @param string $id
300
+     * @param array $notification
301
+     * @return array
302
+     * @throws ActionNotSupportedException
303
+     * @throws AuthenticationFailedException
304
+     * @throws BadRequestException
305
+     * @throws \OC\HintException
306
+     */
307
+    private function shareAccepted($id, $notification) {
308
+
309
+        if (!$this->isS2SEnabled()) {
310
+            throw new ActionNotSupportedException('Server does not support federated cloud sharing');
311
+        }
312
+
313
+        if (!isset($notification['sharedSecret'])) {
314
+            throw new BadRequestException(['sharedSecret']);
315
+        }
316
+
317
+        $token = $notification['sharedSecret'];
318
+
319
+        $share = $this->federatedShareProvider->getShareById($id);
320
+
321
+        $this->verifyShare($share, $token);
322
+        $this->executeAcceptShare($share);
323
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
324
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
325
+            $remoteId = $this->federatedShareProvider->getRemoteId($share);
326
+            $notification = $this->cloudFederationFactory->getCloudFederationNotification();
327
+            $notification->setMessage(
328
+                'SHARE_ACCEPTED',
329
+                'file',
330
+                $remoteId,
331
+                [
332
+                    'sharedSecret' => $token,
333
+                    'message' => 'Recipient accepted the re-share'
334
+                ]
335
+
336
+            );
337
+            $this->cloudFederationProviderManager->sendNotification($remote, $notification);
338
+
339
+        }
340
+
341
+        return [];
342
+    }
343
+
344
+    /**
345
+     * @param IShare $share
346
+     * @throws ShareNotFound
347
+     */
348
+    protected function executeAcceptShare(IShare $share) {
349
+        try {
350
+            $fileId = (int)$share->getNode()->getId();
351
+            list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
352
+        } catch (\Exception $e) {
353
+            throw new ShareNotFound();
354
+        }
355
+
356
+        $event = $this->activityManager->generateEvent();
357
+        $event->setApp('files_sharing')
358
+            ->setType('remote_share')
359
+            ->setAffectedUser($this->getCorrectUid($share))
360
+            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), [$fileId => $file]])
361
+            ->setObject('files', $fileId, $file)
362
+            ->setLink($link);
363
+        $this->activityManager->publish($event);
364
+    }
365
+
366
+    /**
367
+     * process notification that the recipient declined a share
368
+     *
369
+     * @param string $id
370
+     * @param array $notification
371
+     * @return array
372
+     * @throws ActionNotSupportedException
373
+     * @throws AuthenticationFailedException
374
+     * @throws BadRequestException
375
+     * @throws ShareNotFound
376
+     * @throws \OC\HintException
377
+     *
378
+     */
379
+    protected function shareDeclined($id, $notification) {
380
+
381
+        if (!$this->isS2SEnabled()) {
382
+            throw new ActionNotSupportedException('Server does not support federated cloud sharing');
383
+        }
384
+
385
+        if (!isset($notification['sharedSecret'])) {
386
+            throw new BadRequestException(['sharedSecret']);
387
+        }
388
+
389
+        $token = $notification['sharedSecret'];
390
+
391
+        $share = $this->federatedShareProvider->getShareById($id);
392
+
393
+        $this->verifyShare($share, $token);
394
+
395
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
396
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
397
+            $remoteId = $this->federatedShareProvider->getRemoteId($share);
398
+            $notification = $this->cloudFederationFactory->getCloudFederationNotification();
399
+            $notification->setMessage(
400
+                'SHARE_DECLINED',
401
+                'file',
402
+                $remoteId,
403
+                [
404
+                    'sharedSecret' => $token,
405
+                    'message' => 'Recipient declined the re-share'
406
+                ]
407
+
408
+            );
409
+            $this->cloudFederationProviderManager->sendNotification($remote, $notification);
410
+        }
411
+
412
+        $this->executeDeclineShare($share);
413
+
414
+        return [];
415
+
416
+    }
417
+
418
+    /**
419
+     * delete declined share and create a activity
420
+     *
421
+     * @param IShare $share
422
+     * @throws ShareNotFound
423
+     */
424
+    protected function executeDeclineShare(IShare $share) {
425
+        $this->federatedShareProvider->removeShareFromTable($share);
426
+
427
+        try {
428
+            $fileId = (int)$share->getNode()->getId();
429
+            list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
430
+        } catch (\Exception $e) {
431
+            throw new ShareNotFound();
432
+        }
433
+
434
+        $event = $this->activityManager->generateEvent();
435
+        $event->setApp('files_sharing')
436
+            ->setType('remote_share')
437
+            ->setAffectedUser($this->getCorrectUid($share))
438
+            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]])
439
+            ->setObject('files', $fileId, $file)
440
+            ->setLink($link);
441
+        $this->activityManager->publish($event);
442
+
443
+    }
444
+
445
+    /**
446
+     * received the notification that the owner unshared a file from you
447
+     *
448
+     * @param string $id
449
+     * @param string $notification
450
+     * @return array
451
+     * @throws AuthenticationFailedException
452
+     * @throws BadRequestException
453
+     */
454
+    private function undoReshare($id, $notification) {
455
+        if (!isset($notification['sharedSecret'])) {
456
+            throw new BadRequestException(['sharedSecret']);
457
+        }
458
+        $token = $notification['sharedSecret'];
459
+
460
+        $share = $this->federatedShareProvider->getShareById($id);
461
+
462
+        $this->verifyShare($share, $token);
463
+        $this->federatedShareProvider->removeShareFromTable($share);
464
+        return [];
465
+    }
466
+
467
+    /**
468
+     * unshare file from self
469
+     *
470
+     * @param string $id
471
+     * @param array $notification
472
+     * @return array
473
+     * @throws ActionNotSupportedException
474
+     * @throws BadRequestException
475
+     */
476
+    private function unshare($id, array $notification) {
477
+
478
+        if (!$this->isS2SEnabled(true)) {
479
+            throw new ActionNotSupportedException("incoming shares disabled!");
480
+        }
481
+
482
+        if (!isset($notification['sharedSecret'])) {
483
+            throw new BadRequestException(['sharedSecret']);
484
+        }
485
+        $token = $notification['sharedSecret'];
486
+
487
+        $qb = $this->connection->getQueryBuilder();
488
+        $qb->select('*')
489
+            ->from('share_external')
490
+            ->where(
491
+                $qb->expr()->andX(
492
+                    $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
493
+                    $qb->expr()->eq('share_token', $qb->createNamedParameter($token))
494
+                )
495
+            );
496
+
497
+        $result = $qb->execute();
498
+        $share = $result->fetch();
499
+        $result->closeCursor();
500
+
501
+        if ($token && $id && !empty($share)) {
502
+
503
+            $remote = $this->cleanupRemote($share['remote']);
504
+
505
+            $owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
506
+            $mountpoint = $share['mountpoint'];
507
+            $user = $share['user'];
508
+
509
+            $qb = $this->connection->getQueryBuilder();
510
+            $qb->delete('share_external')
511
+                ->where(
512
+                    $qb->expr()->andX(
513
+                        $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
514
+                        $qb->expr()->eq('share_token', $qb->createNamedParameter($token))
515
+                    )
516
+                );
517
+
518
+            $qb->execute();
519
+
520
+            if ($share['accepted']) {
521
+                $path = trim($mountpoint, '/');
522
+            } else {
523
+                $path = trim($share['name'], '/');
524
+            }
525
+
526
+            $notification = $this->notificationManager->createNotification();
527
+            $notification->setApp('files_sharing')
528
+                ->setUser($share['user'])
529
+                ->setObject('remote_share', (int)$share['id']);
530
+            $this->notificationManager->markProcessed($notification);
531
+
532
+            $event = $this->activityManager->generateEvent();
533
+            $event->setApp('files_sharing')
534
+                ->setType('remote_share')
535
+                ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
536
+                ->setAffectedUser($user)
537
+                ->setObject('remote_share', (int)$share['id'], $path);
538
+            \OC::$server->getActivityManager()->publish($event);
539
+        }
540
+
541
+        return [];
542
+    }
543
+
544
+    private function cleanupRemote($remote) {
545
+        $remote = substr($remote, strpos($remote, '://') + 3);
546
+
547
+        return rtrim($remote, '/');
548
+    }
549
+
550
+    /**
551
+     * recipient of a share request to re-share the file with another user
552
+     *
553
+     * @param $id
554
+     * @param $notification
555
+     * @return array
556
+     * @throws AuthenticationFailedException
557
+     * @throws BadRequestException
558
+     * @throws ProviderCouldNotAddShareException
559
+     * @throws ShareNotFound
560
+     */
561
+    protected function reshareRequested($id, $notification) {
562
+
563
+        if (!isset($notification['sharedSecret'])) {
564
+            throw new BadRequestException(['sharedSecret']);
565
+        }
566
+        $token = $notification['sharedSecret'];
567
+
568
+        if (!isset($notification['shareWith'])) {
569
+            throw new BadRequestException(['shareWith']);
570
+        }
571
+        $shareWith = $notification['shareWith'];
572
+
573
+        if (!isset($notification['senderId'])) {
574
+            throw new BadRequestException(['senderId']);
575
+        }
576
+        $senderId = $notification['senderId'];
577
+
578
+        $share = $this->federatedShareProvider->getShareById($id);
579
+        // don't allow to share a file back to the owner
580
+        try {
581
+            list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
582
+            $owner = $share->getShareOwner();
583
+            $currentServer = $this->addressHandler->generateRemoteURL();
584
+            if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
585
+                throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
586
+            }
587
+        } catch (\Exception $e) {
588
+            throw new ProviderCouldNotAddShareException($e->getMessage());
589
+        }
590
+
591
+        $this->verifyShare($share, $token);
592
+
593
+        // check if re-sharing is allowed
594
+        if ($share->getPermissions() & Constants::PERMISSION_SHARE) {
595
+            // the recipient of the initial share is now the initiator for the re-share
596
+            $share->setSharedBy($share->getSharedWith());
597
+            $share->setSharedWith($shareWith);
598
+            $result = $this->federatedShareProvider->create($share);
599
+            $this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
600
+            return ['token' => $result->getToken(), 'providerId' => $result->getId()];
601
+        } else {
602
+            throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
603
+        }
604
+
605
+        throw new BadRequestException([]);
606
+    }
607
+
608
+    /**
609
+     * update permission of a re-share so that the share dialog shows the right
610
+     * permission if the owner or the sender changes the permission
611
+     *
612
+     * @param string $id
613
+     * @param array $notification
614
+     * @return array
615
+     * @throws AuthenticationFailedException
616
+     * @throws BadRequestException
617
+     */
618
+    protected function updateResharePermissions($id, $notification) {
619
+
620
+        if (!isset($notification['sharedSecret'])) {
621
+            throw new BadRequestException(['sharedSecret']);
622
+        }
623
+        $token = $notification['sharedSecret'];
624
+
625
+        if (!isset($notification['permission'])) {
626
+            throw new BadRequestException(['permission']);
627
+        }
628
+        $ocmPermissions = $notification['permission'];
629
+
630
+        $share = $this->federatedShareProvider->getShareById($id);
631
+
632
+        $ncPermission = $this->ocmPermissions2ncPermissions($ocmPermissions);
633
+
634
+        $this->verifyShare($share, $token);
635
+        $this->updatePermissionsInDatabase($share, $ncPermission);
636
+
637
+        return [];
638
+    }
639
+
640
+    /**
641
+     * translate OCM Permissions to Nextcloud permissions
642
+     *
643
+     * @param $ocmPermissions
644
+     * @return int
645
+     * @throws BadRequestException
646
+     */
647
+    protected function ocmPermissions2ncPermissions($ocmPermissions) {
648
+        error_log("ocm permissions: " . json_encode($ocmPermissions));
649
+        $ncPermissions = 0;
650
+        foreach($ocmPermissions as $permission) {
651
+            switch (strtolower($permission)) {
652
+                case 'read':
653
+                    $ncPermissions += Constants::PERMISSION_READ;
654
+                    break;
655
+                case 'write':
656
+                    $ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
657
+                    break;
658
+                case 'share':
659
+                    $ncPermissions += Constants::PERMISSION_SHARE;
660
+                    break;
661
+                default:
662
+                    throw new BadRequestException(['permission']);
663
+            }
664
+
665
+            error_log("new permissions: " . $ncPermissions);
666
+        }
667
+
668
+        return $ncPermissions;
669
+    }
670
+
671
+    /**
672
+     * update permissions in database
673
+     *
674
+     * @param IShare $share
675
+     * @param int $permissions
676
+     */
677
+    protected function updatePermissionsInDatabase(IShare $share, $permissions) {
678
+        $query = $this->connection->getQueryBuilder();
679
+        $query->update('share')
680
+            ->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
681
+            ->set('permissions', $query->createNamedParameter($permissions))
682
+            ->execute();
683
+    }
684
+
685
+
686
+    /**
687
+     * get file
688
+     *
689
+     * @param string $user
690
+     * @param int $fileSource
691
+     * @return array with internal path of the file and a absolute link to it
692
+     */
693
+    private function getFile($user, $fileSource) {
694
+        \OC_Util::setupFS($user);
695
+
696
+        try {
697
+            $file = Filesystem::getPath($fileSource);
698
+        } catch (NotFoundException $e) {
699
+            $file = null;
700
+        }
701
+        $args = Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
702
+        $link = Util::linkToAbsolute('files', 'index.php', $args);
703
+
704
+        return array($file, $link);
705
+
706
+    }
707
+
708
+    /**
709
+     * check if we are the initiator or the owner of a re-share and return the correct UID
710
+     *
711
+     * @param IShare $share
712
+     * @return string
713
+     */
714
+    protected function getCorrectUid(IShare $share) {
715
+        if ($this->userManager->userExists($share->getShareOwner())) {
716
+            return $share->getShareOwner();
717
+        }
718
+
719
+        return $share->getSharedBy();
720
+    }
721
+
722
+
723
+
724
+    /**
725
+     * check if we got the right share
726
+     *
727
+     * @param IShare $share
728
+     * @param string $token
729
+     * @return bool
730
+     * @throws AuthenticationFailedException
731
+     */
732
+    protected function verifyShare(IShare $share, $token) {
733
+        if (
734
+            $share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
735
+            $share->getToken() === $token
736
+        ) {
737
+            return true;
738
+        }
739
+
740
+        throw new AuthenticationFailedException();
741
+    }
742
+
743
+
744
+
745
+    /**
746
+     * check if server-to-server sharing is enabled
747
+     *
748
+     * @param bool $incoming
749
+     * @return bool
750
+     */
751
+    private function isS2SEnabled($incoming = false) {
752
+
753
+        $result = $this->appManager->isEnabledForUser('files_sharing');
754
+
755
+        if ($incoming) {
756
+            $result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
757
+        } else {
758
+            $result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
759
+        }
760
+
761
+        return $result;
762
+    }
763 763
 
764 764
 
765 765
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -186,16 +186,16 @@  discard block
 block discarded – undo
186 186
 			}
187 187
 
188 188
 			// FIXME this should be a method in the user management instead
189
-			$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
189
+			$this->logger->debug('shareWith before, '.$shareWith, ['app' => 'files_sharing']);
190 190
 			Util::emitHook(
191 191
 				'\OCA\Files_Sharing\API\Server2Server',
192 192
 				'preLoginNameUsedAsUserName',
193 193
 				array('uid' => &$shareWith)
194 194
 			);
195
-			$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
195
+			$this->logger->debug('shareWith after, '.$shareWith, ['app' => 'files_sharing']);
196 196
 
197 197
 			if (!$this->userManager->userExists($shareWith)) {
198
-				throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
198
+				throw new ProviderCouldNotAddShareException('User does not exists', '', Http::STATUS_BAD_REQUEST);
199 199
 			}
200 200
 
201 201
 			\OC_Util::setupFS($shareWith);
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
 					->setType('remote_share')
222 222
 					->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
223 223
 					->setAffectedUser($shareWith)
224
-					->setObject('remote_share', (int)$shareId, $name);
224
+					->setObject('remote_share', (int) $shareId, $name);
225 225
 				\OC::$server->getActivityManager()->publish($event);
226 226
 
227 227
 				$notification = $this->notificationManager->createNotification();
@@ -233,12 +233,12 @@  discard block
 block discarded – undo
233 233
 
234 234
 				$declineAction = $notification->createAction();
235 235
 				$declineAction->setLabel('decline')
236
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
236
+					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/'.$shareId)), 'DELETE');
237 237
 				$notification->addAction($declineAction);
238 238
 
239 239
 				$acceptAction = $notification->createAction();
240 240
 				$acceptAction->setLabel('accept')
241
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
241
+					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/'.$shareId)), 'POST');
242 242
 				$notification->addAction($acceptAction);
243 243
 
244 244
 				$this->notificationManager->notify($notification);
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
 					'level' => Util::ERROR,
251 251
 					'app' => 'files_sharing'
252 252
 				]);
253
-				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
253
+				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from '.$remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
254 254
 			}
255 255
 		}
256 256
 
@@ -347,7 +347,7 @@  discard block
 block discarded – undo
347 347
 	 */
348 348
 	protected function executeAcceptShare(IShare $share) {
349 349
 		try {
350
-			$fileId = (int)$share->getNode()->getId();
350
+			$fileId = (int) $share->getNode()->getId();
351 351
 			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
352 352
 		} catch (\Exception $e) {
353 353
 			throw new ShareNotFound();
@@ -425,7 +425,7 @@  discard block
 block discarded – undo
425 425
 		$this->federatedShareProvider->removeShareFromTable($share);
426 426
 
427 427
 		try {
428
-			$fileId = (int)$share->getNode()->getId();
428
+			$fileId = (int) $share->getNode()->getId();
429 429
 			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
430 430
 		} catch (\Exception $e) {
431 431
 			throw new ShareNotFound();
@@ -526,7 +526,7 @@  discard block
 block discarded – undo
526 526
 			$notification = $this->notificationManager->createNotification();
527 527
 			$notification->setApp('files_sharing')
528 528
 				->setUser($share['user'])
529
-				->setObject('remote_share', (int)$share['id']);
529
+				->setObject('remote_share', (int) $share['id']);
530 530
 			$this->notificationManager->markProcessed($notification);
531 531
 
532 532
 			$event = $this->activityManager->generateEvent();
@@ -534,7 +534,7 @@  discard block
 block discarded – undo
534 534
 				->setType('remote_share')
535 535
 				->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
536 536
 				->setAffectedUser($user)
537
-				->setObject('remote_share', (int)$share['id'], $path);
537
+				->setObject('remote_share', (int) $share['id'], $path);
538 538
 			\OC::$server->getActivityManager()->publish($event);
539 539
 		}
540 540
 
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
 			$owner = $share->getShareOwner();
583 583
 			$currentServer = $this->addressHandler->generateRemoteURL();
584 584
 			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
585
-				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
585
+				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: '.$id);
586 586
 			}
587 587
 		} catch (\Exception $e) {
588 588
 			throw new ProviderCouldNotAddShareException($e->getMessage());
@@ -596,10 +596,10 @@  discard block
 block discarded – undo
596 596
 			$share->setSharedBy($share->getSharedWith());
597 597
 			$share->setSharedWith($shareWith);
598 598
 			$result = $this->federatedShareProvider->create($share);
599
-			$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
599
+			$this->federatedShareProvider->storeRemoteId((int) $result->getId(), $senderId);
600 600
 			return ['token' => $result->getToken(), 'providerId' => $result->getId()];
601 601
 		} else {
602
-			throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
602
+			throw new ProviderCouldNotAddShareException('resharing not allowed for share: '.$id);
603 603
 		}
604 604
 
605 605
 		throw new BadRequestException([]);
@@ -645,9 +645,9 @@  discard block
 block discarded – undo
645 645
 	 * @throws BadRequestException
646 646
 	 */
647 647
 	protected function ocmPermissions2ncPermissions($ocmPermissions) {
648
-		error_log("ocm permissions: " . json_encode($ocmPermissions));
648
+		error_log("ocm permissions: ".json_encode($ocmPermissions));
649 649
 		$ncPermissions = 0;
650
-		foreach($ocmPermissions as $permission) {
650
+		foreach ($ocmPermissions as $permission) {
651 651
 			switch (strtolower($permission)) {
652 652
 				case 'read':
653 653
 					$ncPermissions += Constants::PERMISSION_READ;
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
 					throw new BadRequestException(['permission']);
663 663
 			}
664 664
 
665
-			error_log("new permissions: " . $ncPermissions);
665
+			error_log("new permissions: ".$ncPermissions);
666 666
 		}
667 667
 
668 668
 		return $ncPermissions;
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/FederatedShareProvider.php 2 patches
Indentation   +966 added lines, -966 removed lines patch added patch discarded remove patch
@@ -53,980 +53,980 @@
 block discarded – undo
53 53
  */
54 54
 class FederatedShareProvider implements IShareProvider {
55 55
 
56
-	const SHARE_TYPE_REMOTE = 6;
57
-
58
-	/** @var IDBConnection */
59
-	private $dbConnection;
60
-
61
-	/** @var AddressHandler */
62
-	private $addressHandler;
63
-
64
-	/** @var Notifications */
65
-	private $notifications;
66
-
67
-	/** @var TokenHandler */
68
-	private $tokenHandler;
69
-
70
-	/** @var IL10N */
71
-	private $l;
72
-
73
-	/** @var ILogger */
74
-	private $logger;
75
-
76
-	/** @var IRootFolder */
77
-	private $rootFolder;
78
-
79
-	/** @var IConfig */
80
-	private $config;
81
-
82
-	/** @var string */
83
-	private $externalShareTable = 'share_external';
84
-
85
-	/** @var IUserManager */
86
-	private $userManager;
87
-
88
-	/** @var ICloudIdManager */
89
-	private $cloudIdManager;
90
-
91
-	/** @var \OCP\GlobalScale\IConfig */
92
-	private $gsConfig;
93
-
94
-	/**
95
-	 * DefaultShareProvider constructor.
96
-	 *
97
-	 * @param IDBConnection $connection
98
-	 * @param AddressHandler $addressHandler
99
-	 * @param Notifications $notifications
100
-	 * @param TokenHandler $tokenHandler
101
-	 * @param IL10N $l10n
102
-	 * @param ILogger $logger
103
-	 * @param IRootFolder $rootFolder
104
-	 * @param IConfig $config
105
-	 * @param IUserManager $userManager
106
-	 * @param ICloudIdManager $cloudIdManager
107
-	 * @param \OCP\GlobalScale\IConfig $globalScaleConfig
108
-	 */
109
-	public function __construct(
110
-			IDBConnection $connection,
111
-			AddressHandler $addressHandler,
112
-			Notifications $notifications,
113
-			TokenHandler $tokenHandler,
114
-			IL10N $l10n,
115
-			ILogger $logger,
116
-			IRootFolder $rootFolder,
117
-			IConfig $config,
118
-			IUserManager $userManager,
119
-			ICloudIdManager $cloudIdManager,
120
-			\OCP\GlobalScale\IConfig $globalScaleConfig
121
-	) {
122
-		$this->dbConnection = $connection;
123
-		$this->addressHandler = $addressHandler;
124
-		$this->notifications = $notifications;
125
-		$this->tokenHandler = $tokenHandler;
126
-		$this->l = $l10n;
127
-		$this->logger = $logger;
128
-		$this->rootFolder = $rootFolder;
129
-		$this->config = $config;
130
-		$this->userManager = $userManager;
131
-		$this->cloudIdManager = $cloudIdManager;
132
-		$this->gsConfig = $globalScaleConfig;
133
-	}
134
-
135
-	/**
136
-	 * Return the identifier of this provider.
137
-	 *
138
-	 * @return string Containing only [a-zA-Z0-9]
139
-	 */
140
-	public function identifier() {
141
-		return 'ocFederatedSharing';
142
-	}
143
-
144
-	/**
145
-	 * Share a path
146
-	 *
147
-	 * @param IShare $share
148
-	 * @return IShare The share object
149
-	 * @throws ShareNotFound
150
-	 * @throws \Exception
151
-	 */
152
-	public function create(IShare $share) {
153
-
154
-		$shareWith = $share->getSharedWith();
155
-		$itemSource = $share->getNodeId();
156
-		$itemType = $share->getNodeType();
157
-		$permissions = $share->getPermissions();
158
-		$sharedBy = $share->getSharedBy();
159
-
160
-		/*
56
+    const SHARE_TYPE_REMOTE = 6;
57
+
58
+    /** @var IDBConnection */
59
+    private $dbConnection;
60
+
61
+    /** @var AddressHandler */
62
+    private $addressHandler;
63
+
64
+    /** @var Notifications */
65
+    private $notifications;
66
+
67
+    /** @var TokenHandler */
68
+    private $tokenHandler;
69
+
70
+    /** @var IL10N */
71
+    private $l;
72
+
73
+    /** @var ILogger */
74
+    private $logger;
75
+
76
+    /** @var IRootFolder */
77
+    private $rootFolder;
78
+
79
+    /** @var IConfig */
80
+    private $config;
81
+
82
+    /** @var string */
83
+    private $externalShareTable = 'share_external';
84
+
85
+    /** @var IUserManager */
86
+    private $userManager;
87
+
88
+    /** @var ICloudIdManager */
89
+    private $cloudIdManager;
90
+
91
+    /** @var \OCP\GlobalScale\IConfig */
92
+    private $gsConfig;
93
+
94
+    /**
95
+     * DefaultShareProvider constructor.
96
+     *
97
+     * @param IDBConnection $connection
98
+     * @param AddressHandler $addressHandler
99
+     * @param Notifications $notifications
100
+     * @param TokenHandler $tokenHandler
101
+     * @param IL10N $l10n
102
+     * @param ILogger $logger
103
+     * @param IRootFolder $rootFolder
104
+     * @param IConfig $config
105
+     * @param IUserManager $userManager
106
+     * @param ICloudIdManager $cloudIdManager
107
+     * @param \OCP\GlobalScale\IConfig $globalScaleConfig
108
+     */
109
+    public function __construct(
110
+            IDBConnection $connection,
111
+            AddressHandler $addressHandler,
112
+            Notifications $notifications,
113
+            TokenHandler $tokenHandler,
114
+            IL10N $l10n,
115
+            ILogger $logger,
116
+            IRootFolder $rootFolder,
117
+            IConfig $config,
118
+            IUserManager $userManager,
119
+            ICloudIdManager $cloudIdManager,
120
+            \OCP\GlobalScale\IConfig $globalScaleConfig
121
+    ) {
122
+        $this->dbConnection = $connection;
123
+        $this->addressHandler = $addressHandler;
124
+        $this->notifications = $notifications;
125
+        $this->tokenHandler = $tokenHandler;
126
+        $this->l = $l10n;
127
+        $this->logger = $logger;
128
+        $this->rootFolder = $rootFolder;
129
+        $this->config = $config;
130
+        $this->userManager = $userManager;
131
+        $this->cloudIdManager = $cloudIdManager;
132
+        $this->gsConfig = $globalScaleConfig;
133
+    }
134
+
135
+    /**
136
+     * Return the identifier of this provider.
137
+     *
138
+     * @return string Containing only [a-zA-Z0-9]
139
+     */
140
+    public function identifier() {
141
+        return 'ocFederatedSharing';
142
+    }
143
+
144
+    /**
145
+     * Share a path
146
+     *
147
+     * @param IShare $share
148
+     * @return IShare The share object
149
+     * @throws ShareNotFound
150
+     * @throws \Exception
151
+     */
152
+    public function create(IShare $share) {
153
+
154
+        $shareWith = $share->getSharedWith();
155
+        $itemSource = $share->getNodeId();
156
+        $itemType = $share->getNodeType();
157
+        $permissions = $share->getPermissions();
158
+        $sharedBy = $share->getSharedBy();
159
+
160
+        /*
161 161
 		 * Check if file is not already shared with the remote user
162 162
 		 */
163
-		$alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0);
164
-		if (!empty($alreadyShared)) {
165
-			$message = 'Sharing %s failed, because this item is already shared with %s';
166
-			$message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
167
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
168
-			throw new \Exception($message_t);
169
-		}
170
-
171
-
172
-		// don't allow federated shares if source and target server are the same
173
-		$cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
174
-		$currentServer = $this->addressHandler->generateRemoteURL();
175
-		$currentUser = $sharedBy;
176
-		if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
177
-			$message = 'Not allowed to create a federated share with the same user.';
178
-			$message_t = $this->l->t('Not allowed to create a federated share with the same user');
179
-			$this->logger->debug($message, ['app' => 'Federated File Sharing']);
180
-			throw new \Exception($message_t);
181
-		}
182
-
183
-
184
-		$share->setSharedWith($cloudId->getId());
185
-
186
-		try {
187
-			$remoteShare = $this->getShareFromExternalShareTable($share);
188
-		} catch (ShareNotFound $e) {
189
-			$remoteShare = null;
190
-		}
191
-
192
-		if ($remoteShare) {
193
-			try {
194
-				$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
195
-				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time());
196
-				$share->setId($shareId);
197
-				list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
198
-				// remote share was create successfully if we get a valid token as return
199
-				$send = is_string($token) && $token !== '';
200
-			} catch (\Exception $e) {
201
-				// fall back to old re-share behavior if the remote server
202
-				// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
203
-				$this->removeShareFromTable($share);
204
-				$shareId = $this->createFederatedShare($share);
205
-			}
206
-			if ($send) {
207
-				$this->updateSuccessfulReshare($shareId, $token);
208
-				$this->storeRemoteId($shareId, $remoteId);
209
-			} else {
210
-				$this->removeShareFromTable($share);
211
-				$message_t = $this->l->t('File is already shared with %s', [$shareWith]);
212
-				throw new \Exception($message_t);
213
-			}
214
-
215
-		} else {
216
-			$shareId = $this->createFederatedShare($share);
217
-		}
218
-
219
-		$data = $this->getRawShare($shareId);
220
-		return $this->createShareObject($data);
221
-	}
222
-
223
-	/**
224
-	 * create federated share and inform the recipient
225
-	 *
226
-	 * @param IShare $share
227
-	 * @return int
228
-	 * @throws ShareNotFound
229
-	 * @throws \Exception
230
-	 */
231
-	protected function createFederatedShare(IShare $share) {
232
-		$token = $this->tokenHandler->generateToken();
233
-		$shareId = $this->addShareToDB(
234
-			$share->getNodeId(),
235
-			$share->getNodeType(),
236
-			$share->getSharedWith(),
237
-			$share->getSharedBy(),
238
-			$share->getShareOwner(),
239
-			$share->getPermissions(),
240
-			$token
241
-		);
242
-
243
-		$failure = false;
244
-
245
-		try {
246
-			$sharedByFederatedId = $share->getSharedBy();
247
-			if ($this->userManager->userExists($sharedByFederatedId)) {
248
-				$cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
249
-				$sharedByFederatedId = $cloudId->getId();
250
-			}
251
-			$ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
252
-			$send = $this->notifications->sendRemoteShare(
253
-				$token,
254
-				$share->getSharedWith(),
255
-				$share->getNode()->getName(),
256
-				$shareId,
257
-				$share->getShareOwner(),
258
-				$ownerCloudId->getId(),
259
-				$share->getSharedBy(),
260
-				$sharedByFederatedId
261
-			);
262
-
263
-			if ($send === false) {
264
-				$failure = true;
265
-			}
266
-		} catch (\Exception $e) {
267
-			$this->logger->logException($e, [
268
-				'message' => 'Failed to notify remote server of federated share, removing share.',
269
-				'level' => ILogger::ERROR,
270
-				'app' => 'federatedfilesharing',
271
-			]);
272
-			$failure = true;
273
-		}
274
-
275
-		if($failure) {
276
-			$this->removeShareFromTableById($shareId);
277
-			$message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate.',
278
-				[$share->getNode()->getName(), $share->getSharedWith()]);
279
-			throw new \Exception($message_t);
280
-		}
281
-
282
-		return $shareId;
283
-
284
-	}
285
-
286
-	/**
287
-	 * @param string $shareWith
288
-	 * @param IShare $share
289
-	 * @param string $shareId internal share Id
290
-	 * @return array
291
-	 * @throws \Exception
292
-	 */
293
-	protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
294
-
295
-		$remoteShare = $this->getShareFromExternalShareTable($share);
296
-		$token = $remoteShare['share_token'];
297
-		$remoteId = $remoteShare['remote_id'];
298
-		$remote = $remoteShare['remote'];
299
-
300
-		list($token, $remoteId) = $this->notifications->requestReShare(
301
-			$token,
302
-			$remoteId,
303
-			$shareId,
304
-			$remote,
305
-			$shareWith,
306
-			$share->getPermissions(),
307
-			$share->getNode()->getName()
308
-		);
309
-
310
-		return [$token, $remoteId];
311
-	}
312
-
313
-	/**
314
-	 * get federated share from the share_external table but exclude mounted link shares
315
-	 *
316
-	 * @param IShare $share
317
-	 * @return array
318
-	 * @throws ShareNotFound
319
-	 */
320
-	protected function getShareFromExternalShareTable(IShare $share) {
321
-		$query = $this->dbConnection->getQueryBuilder();
322
-		$query->select('*')->from($this->externalShareTable)
323
-			->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
324
-			->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
325
-		$result = $query->execute()->fetchAll();
326
-
327
-		if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
328
-			return $result[0];
329
-		}
330
-
331
-		throw new ShareNotFound('share not found in share_external table');
332
-	}
333
-
334
-	/**
335
-	 * add share to the database and return the ID
336
-	 *
337
-	 * @param int $itemSource
338
-	 * @param string $itemType
339
-	 * @param string $shareWith
340
-	 * @param string $sharedBy
341
-	 * @param string $uidOwner
342
-	 * @param int $permissions
343
-	 * @param string $token
344
-	 * @return int
345
-	 */
346
-	private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) {
347
-		$qb = $this->dbConnection->getQueryBuilder();
348
-		$qb->insert('share')
349
-			->setValue('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))
350
-			->setValue('item_type', $qb->createNamedParameter($itemType))
351
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
352
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
353
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
354
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
355
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
356
-			->setValue('permissions', $qb->createNamedParameter($permissions))
357
-			->setValue('token', $qb->createNamedParameter($token))
358
-			->setValue('stime', $qb->createNamedParameter(time()));
359
-
360
-		/*
163
+        $alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0);
164
+        if (!empty($alreadyShared)) {
165
+            $message = 'Sharing %s failed, because this item is already shared with %s';
166
+            $message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
167
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
168
+            throw new \Exception($message_t);
169
+        }
170
+
171
+
172
+        // don't allow federated shares if source and target server are the same
173
+        $cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
174
+        $currentServer = $this->addressHandler->generateRemoteURL();
175
+        $currentUser = $sharedBy;
176
+        if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
177
+            $message = 'Not allowed to create a federated share with the same user.';
178
+            $message_t = $this->l->t('Not allowed to create a federated share with the same user');
179
+            $this->logger->debug($message, ['app' => 'Federated File Sharing']);
180
+            throw new \Exception($message_t);
181
+        }
182
+
183
+
184
+        $share->setSharedWith($cloudId->getId());
185
+
186
+        try {
187
+            $remoteShare = $this->getShareFromExternalShareTable($share);
188
+        } catch (ShareNotFound $e) {
189
+            $remoteShare = null;
190
+        }
191
+
192
+        if ($remoteShare) {
193
+            try {
194
+                $ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
195
+                $shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time());
196
+                $share->setId($shareId);
197
+                list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
198
+                // remote share was create successfully if we get a valid token as return
199
+                $send = is_string($token) && $token !== '';
200
+            } catch (\Exception $e) {
201
+                // fall back to old re-share behavior if the remote server
202
+                // doesn't support flat re-shares (was introduced with Nextcloud 9.1)
203
+                $this->removeShareFromTable($share);
204
+                $shareId = $this->createFederatedShare($share);
205
+            }
206
+            if ($send) {
207
+                $this->updateSuccessfulReshare($shareId, $token);
208
+                $this->storeRemoteId($shareId, $remoteId);
209
+            } else {
210
+                $this->removeShareFromTable($share);
211
+                $message_t = $this->l->t('File is already shared with %s', [$shareWith]);
212
+                throw new \Exception($message_t);
213
+            }
214
+
215
+        } else {
216
+            $shareId = $this->createFederatedShare($share);
217
+        }
218
+
219
+        $data = $this->getRawShare($shareId);
220
+        return $this->createShareObject($data);
221
+    }
222
+
223
+    /**
224
+     * create federated share and inform the recipient
225
+     *
226
+     * @param IShare $share
227
+     * @return int
228
+     * @throws ShareNotFound
229
+     * @throws \Exception
230
+     */
231
+    protected function createFederatedShare(IShare $share) {
232
+        $token = $this->tokenHandler->generateToken();
233
+        $shareId = $this->addShareToDB(
234
+            $share->getNodeId(),
235
+            $share->getNodeType(),
236
+            $share->getSharedWith(),
237
+            $share->getSharedBy(),
238
+            $share->getShareOwner(),
239
+            $share->getPermissions(),
240
+            $token
241
+        );
242
+
243
+        $failure = false;
244
+
245
+        try {
246
+            $sharedByFederatedId = $share->getSharedBy();
247
+            if ($this->userManager->userExists($sharedByFederatedId)) {
248
+                $cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
249
+                $sharedByFederatedId = $cloudId->getId();
250
+            }
251
+            $ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
252
+            $send = $this->notifications->sendRemoteShare(
253
+                $token,
254
+                $share->getSharedWith(),
255
+                $share->getNode()->getName(),
256
+                $shareId,
257
+                $share->getShareOwner(),
258
+                $ownerCloudId->getId(),
259
+                $share->getSharedBy(),
260
+                $sharedByFederatedId
261
+            );
262
+
263
+            if ($send === false) {
264
+                $failure = true;
265
+            }
266
+        } catch (\Exception $e) {
267
+            $this->logger->logException($e, [
268
+                'message' => 'Failed to notify remote server of federated share, removing share.',
269
+                'level' => ILogger::ERROR,
270
+                'app' => 'federatedfilesharing',
271
+            ]);
272
+            $failure = true;
273
+        }
274
+
275
+        if($failure) {
276
+            $this->removeShareFromTableById($shareId);
277
+            $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate.',
278
+                [$share->getNode()->getName(), $share->getSharedWith()]);
279
+            throw new \Exception($message_t);
280
+        }
281
+
282
+        return $shareId;
283
+
284
+    }
285
+
286
+    /**
287
+     * @param string $shareWith
288
+     * @param IShare $share
289
+     * @param string $shareId internal share Id
290
+     * @return array
291
+     * @throws \Exception
292
+     */
293
+    protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
294
+
295
+        $remoteShare = $this->getShareFromExternalShareTable($share);
296
+        $token = $remoteShare['share_token'];
297
+        $remoteId = $remoteShare['remote_id'];
298
+        $remote = $remoteShare['remote'];
299
+
300
+        list($token, $remoteId) = $this->notifications->requestReShare(
301
+            $token,
302
+            $remoteId,
303
+            $shareId,
304
+            $remote,
305
+            $shareWith,
306
+            $share->getPermissions(),
307
+            $share->getNode()->getName()
308
+        );
309
+
310
+        return [$token, $remoteId];
311
+    }
312
+
313
+    /**
314
+     * get federated share from the share_external table but exclude mounted link shares
315
+     *
316
+     * @param IShare $share
317
+     * @return array
318
+     * @throws ShareNotFound
319
+     */
320
+    protected function getShareFromExternalShareTable(IShare $share) {
321
+        $query = $this->dbConnection->getQueryBuilder();
322
+        $query->select('*')->from($this->externalShareTable)
323
+            ->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
324
+            ->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
325
+        $result = $query->execute()->fetchAll();
326
+
327
+        if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
328
+            return $result[0];
329
+        }
330
+
331
+        throw new ShareNotFound('share not found in share_external table');
332
+    }
333
+
334
+    /**
335
+     * add share to the database and return the ID
336
+     *
337
+     * @param int $itemSource
338
+     * @param string $itemType
339
+     * @param string $shareWith
340
+     * @param string $sharedBy
341
+     * @param string $uidOwner
342
+     * @param int $permissions
343
+     * @param string $token
344
+     * @return int
345
+     */
346
+    private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) {
347
+        $qb = $this->dbConnection->getQueryBuilder();
348
+        $qb->insert('share')
349
+            ->setValue('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))
350
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
351
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
352
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
353
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
354
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
355
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
356
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
357
+            ->setValue('token', $qb->createNamedParameter($token))
358
+            ->setValue('stime', $qb->createNamedParameter(time()));
359
+
360
+        /*
361 361
 		 * Added to fix https://github.com/owncloud/core/issues/22215
362 362
 		 * Can be removed once we get rid of ajax/share.php
363 363
 		 */
364
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
365
-
366
-		$qb->execute();
367
-		$id = $qb->getLastInsertId();
368
-
369
-		return (int)$id;
370
-	}
371
-
372
-	/**
373
-	 * Update a share
374
-	 *
375
-	 * @param IShare $share
376
-	 * @return IShare The share object
377
-	 */
378
-	public function update(IShare $share) {
379
-		/*
364
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
365
+
366
+        $qb->execute();
367
+        $id = $qb->getLastInsertId();
368
+
369
+        return (int)$id;
370
+    }
371
+
372
+    /**
373
+     * Update a share
374
+     *
375
+     * @param IShare $share
376
+     * @return IShare The share object
377
+     */
378
+    public function update(IShare $share) {
379
+        /*
380 380
 		 * We allow updating the permissions of federated shares
381 381
 		 */
382
-		$qb = $this->dbConnection->getQueryBuilder();
383
-			$qb->update('share')
384
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
385
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
386
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
387
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
388
-				->execute();
389
-
390
-		// send the updated permission to the owner/initiator, if they are not the same
391
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
392
-			$this->sendPermissionUpdate($share);
393
-		}
394
-
395
-		return $share;
396
-	}
397
-
398
-	/**
399
-	 * send the updated permission to the owner/initiator, if they are not the same
400
-	 *
401
-	 * @param IShare $share
402
-	 * @throws ShareNotFound
403
-	 * @throws \OC\HintException
404
-	 */
405
-	protected function sendPermissionUpdate(IShare $share) {
406
-		$remoteId = $this->getRemoteId($share);
407
-		// if the local user is the owner we send the permission change to the initiator
408
-		if ($this->userManager->userExists($share->getShareOwner())) {
409
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
410
-		} else { // ... if not we send the permission change to the owner
411
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
412
-		}
413
-		$this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
414
-	}
415
-
416
-
417
-	/**
418
-	 * update successful reShare with the correct token
419
-	 *
420
-	 * @param int $shareId
421
-	 * @param string $token
422
-	 */
423
-	protected function updateSuccessfulReShare($shareId, $token) {
424
-		$query = $this->dbConnection->getQueryBuilder();
425
-		$query->update('share')
426
-			->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
427
-			->set('token', $query->createNamedParameter($token))
428
-			->execute();
429
-	}
430
-
431
-	/**
432
-	 * store remote ID in federated reShare table
433
-	 *
434
-	 * @param $shareId
435
-	 * @param $remoteId
436
-	 */
437
-	public function storeRemoteId($shareId, $remoteId) {
438
-		$query = $this->dbConnection->getQueryBuilder();
439
-		$query->insert('federated_reshares')
440
-			->values(
441
-				[
442
-					'share_id' =>  $query->createNamedParameter($shareId),
443
-					'remote_id' => $query->createNamedParameter($remoteId),
444
-				]
445
-			);
446
-		$query->execute();
447
-	}
448
-
449
-	/**
450
-	 * get share ID on remote server for federated re-shares
451
-	 *
452
-	 * @param IShare $share
453
-	 * @return int
454
-	 * @throws ShareNotFound
455
-	 */
456
-	public function getRemoteId(IShare $share) {
457
-		$query = $this->dbConnection->getQueryBuilder();
458
-		$query->select('remote_id')->from('federated_reshares')
459
-			->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
460
-		$data = $query->execute()->fetch();
461
-
462
-		if (!is_array($data) || !isset($data['remote_id'])) {
463
-			throw new ShareNotFound();
464
-		}
465
-
466
-		return (int)$data['remote_id'];
467
-	}
468
-
469
-	/**
470
-	 * @inheritdoc
471
-	 */
472
-	public function move(IShare $share, $recipient) {
473
-		/*
382
+        $qb = $this->dbConnection->getQueryBuilder();
383
+            $qb->update('share')
384
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
385
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
386
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
387
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
388
+                ->execute();
389
+
390
+        // send the updated permission to the owner/initiator, if they are not the same
391
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
392
+            $this->sendPermissionUpdate($share);
393
+        }
394
+
395
+        return $share;
396
+    }
397
+
398
+    /**
399
+     * send the updated permission to the owner/initiator, if they are not the same
400
+     *
401
+     * @param IShare $share
402
+     * @throws ShareNotFound
403
+     * @throws \OC\HintException
404
+     */
405
+    protected function sendPermissionUpdate(IShare $share) {
406
+        $remoteId = $this->getRemoteId($share);
407
+        // if the local user is the owner we send the permission change to the initiator
408
+        if ($this->userManager->userExists($share->getShareOwner())) {
409
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
410
+        } else { // ... if not we send the permission change to the owner
411
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
412
+        }
413
+        $this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
414
+    }
415
+
416
+
417
+    /**
418
+     * update successful reShare with the correct token
419
+     *
420
+     * @param int $shareId
421
+     * @param string $token
422
+     */
423
+    protected function updateSuccessfulReShare($shareId, $token) {
424
+        $query = $this->dbConnection->getQueryBuilder();
425
+        $query->update('share')
426
+            ->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
427
+            ->set('token', $query->createNamedParameter($token))
428
+            ->execute();
429
+    }
430
+
431
+    /**
432
+     * store remote ID in federated reShare table
433
+     *
434
+     * @param $shareId
435
+     * @param $remoteId
436
+     */
437
+    public function storeRemoteId($shareId, $remoteId) {
438
+        $query = $this->dbConnection->getQueryBuilder();
439
+        $query->insert('federated_reshares')
440
+            ->values(
441
+                [
442
+                    'share_id' =>  $query->createNamedParameter($shareId),
443
+                    'remote_id' => $query->createNamedParameter($remoteId),
444
+                ]
445
+            );
446
+        $query->execute();
447
+    }
448
+
449
+    /**
450
+     * get share ID on remote server for federated re-shares
451
+     *
452
+     * @param IShare $share
453
+     * @return int
454
+     * @throws ShareNotFound
455
+     */
456
+    public function getRemoteId(IShare $share) {
457
+        $query = $this->dbConnection->getQueryBuilder();
458
+        $query->select('remote_id')->from('federated_reshares')
459
+            ->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
460
+        $data = $query->execute()->fetch();
461
+
462
+        if (!is_array($data) || !isset($data['remote_id'])) {
463
+            throw new ShareNotFound();
464
+        }
465
+
466
+        return (int)$data['remote_id'];
467
+    }
468
+
469
+    /**
470
+     * @inheritdoc
471
+     */
472
+    public function move(IShare $share, $recipient) {
473
+        /*
474 474
 		 * This function does nothing yet as it is just for outgoing
475 475
 		 * federated shares.
476 476
 		 */
477
-		return $share;
478
-	}
479
-
480
-	/**
481
-	 * Get all children of this share
482
-	 *
483
-	 * @param IShare $parent
484
-	 * @return IShare[]
485
-	 */
486
-	public function getChildren(IShare $parent) {
487
-		$children = [];
488
-
489
-		$qb = $this->dbConnection->getQueryBuilder();
490
-		$qb->select('*')
491
-			->from('share')
492
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
493
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
494
-			->orderBy('id');
495
-
496
-		$cursor = $qb->execute();
497
-		while($data = $cursor->fetch()) {
498
-			$children[] = $this->createShareObject($data);
499
-		}
500
-		$cursor->closeCursor();
501
-
502
-		return $children;
503
-	}
504
-
505
-	/**
506
-	 * Delete a share (owner unShares the file)
507
-	 *
508
-	 * @param IShare $share
509
-	 */
510
-	public function delete(IShare $share) {
511
-
512
-		list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith());
513
-
514
-		$isOwner = false;
515
-
516
-		// if the local user is the owner we can send the unShare request directly...
517
-		if ($this->userManager->userExists($share->getShareOwner())) {
518
-			$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
519
-			$this->revokeShare($share, true);
520
-		} else { // ... if not we need to correct ID for the unShare request
521
-			$remoteId = $this->getRemoteId($share);
522
-			$this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
523
-			$this->revokeShare($share, false);
524
-		}
525
-
526
-		// only remove the share when all messages are send to not lose information
527
-		// about the share to early
528
-		$this->removeShareFromTable($share);
529
-	}
530
-
531
-	/**
532
-	 * in case of a re-share we need to send the other use (initiator or owner)
533
-	 * a message that the file was unshared
534
-	 *
535
-	 * @param IShare $share
536
-	 * @param bool $isOwner the user can either be the owner or the user who re-sahred it
537
-	 * @throws ShareNotFound
538
-	 * @throws \OC\HintException
539
-	 */
540
-	protected function revokeShare($share, $isOwner) {
541
-		// also send a unShare request to the initiator, if this is a different user than the owner
542
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
543
-			if ($isOwner) {
544
-				list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
545
-			} else {
546
-				list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
547
-			}
548
-			$remoteId = $this->getRemoteId($share);
549
-			$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
550
-		}
551
-	}
552
-
553
-	/**
554
-	 * remove share from table
555
-	 *
556
-	 * @param IShare $share
557
-	 */
558
-	public function removeShareFromTable(IShare $share) {
559
-		$this->removeShareFromTableById($share->getId());
560
-	}
561
-
562
-	/**
563
-	 * remove share from table
564
-	 *
565
-	 * @param string $shareId
566
-	 */
567
-	private function removeShareFromTableById($shareId) {
568
-		$qb = $this->dbConnection->getQueryBuilder();
569
-		$qb->delete('share')
570
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
571
-		$qb->execute();
572
-
573
-		$qb->delete('federated_reshares')
574
-			->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId)));
575
-		$qb->execute();
576
-	}
577
-
578
-	/**
579
-	 * @inheritdoc
580
-	 */
581
-	public function deleteFromSelf(IShare $share, $recipient) {
582
-		// nothing to do here. Technically deleteFromSelf in the context of federated
583
-		// shares is a umount of a external storage. This is handled here
584
-		// apps/files_sharing/lib/external/manager.php
585
-		// TODO move this code over to this app
586
-	}
587
-
588
-
589
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
590
-		$qb = $this->dbConnection->getQueryBuilder();
591
-		$qb->select('*')
592
-			->from('share', 's')
593
-			->andWhere($qb->expr()->orX(
594
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
595
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
596
-			))
597
-			->andWhere(
598
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))
599
-			);
600
-
601
-		/**
602
-		 * Reshares for this user are shares where they are the owner.
603
-		 */
604
-		if ($reshares === false) {
605
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
606
-		} else {
607
-			$qb->andWhere(
608
-				$qb->expr()->orX(
609
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
610
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
611
-				)
612
-			);
613
-		}
614
-
615
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
616
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
617
-
618
-		$qb->orderBy('id');
619
-
620
-		$cursor = $qb->execute();
621
-		$shares = [];
622
-		while ($data = $cursor->fetch()) {
623
-			$shares[$data['fileid']][] = $this->createShareObject($data);
624
-		}
625
-		$cursor->closeCursor();
626
-
627
-		return $shares;
628
-	}
629
-
630
-	/**
631
-	 * @inheritdoc
632
-	 */
633
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
634
-		$qb = $this->dbConnection->getQueryBuilder();
635
-		$qb->select('*')
636
-			->from('share');
637
-
638
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
639
-
640
-		/**
641
-		 * Reshares for this user are shares where they are the owner.
642
-		 */
643
-		if ($reshares === false) {
644
-			//Special case for old shares created via the web UI
645
-			$or1 = $qb->expr()->andX(
646
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
647
-				$qb->expr()->isNull('uid_initiator')
648
-			);
649
-
650
-			$qb->andWhere(
651
-				$qb->expr()->orX(
652
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
653
-					$or1
654
-				)
655
-			);
656
-		} else {
657
-			$qb->andWhere(
658
-				$qb->expr()->orX(
659
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
660
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
661
-				)
662
-			);
663
-		}
664
-
665
-		if ($node !== null) {
666
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
667
-		}
668
-
669
-		if ($limit !== -1) {
670
-			$qb->setMaxResults($limit);
671
-		}
672
-
673
-		$qb->setFirstResult($offset);
674
-		$qb->orderBy('id');
675
-
676
-		$cursor = $qb->execute();
677
-		$shares = [];
678
-		while($data = $cursor->fetch()) {
679
-			$shares[] = $this->createShareObject($data);
680
-		}
681
-		$cursor->closeCursor();
682
-
683
-		return $shares;
684
-	}
685
-
686
-	/**
687
-	 * @inheritdoc
688
-	 */
689
-	public function getShareById($id, $recipientId = null) {
690
-		$qb = $this->dbConnection->getQueryBuilder();
691
-
692
-		$qb->select('*')
693
-			->from('share')
694
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
695
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
696
-
697
-		$cursor = $qb->execute();
698
-		$data = $cursor->fetch();
699
-		$cursor->closeCursor();
700
-
701
-		if ($data === false) {
702
-			throw new ShareNotFound('Can not find share with ID: ' . $id);
703
-		}
704
-
705
-		try {
706
-			$share = $this->createShareObject($data);
707
-		} catch (InvalidShare $e) {
708
-			throw new ShareNotFound();
709
-		}
710
-
711
-		return $share;
712
-	}
713
-
714
-	/**
715
-	 * Get shares for a given path
716
-	 *
717
-	 * @param \OCP\Files\Node $path
718
-	 * @return IShare[]
719
-	 */
720
-	public function getSharesByPath(Node $path) {
721
-		$qb = $this->dbConnection->getQueryBuilder();
722
-
723
-		$cursor = $qb->select('*')
724
-			->from('share')
725
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
726
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
727
-			->execute();
728
-
729
-		$shares = [];
730
-		while($data = $cursor->fetch()) {
731
-			$shares[] = $this->createShareObject($data);
732
-		}
733
-		$cursor->closeCursor();
734
-
735
-		return $shares;
736
-	}
737
-
738
-	/**
739
-	 * @inheritdoc
740
-	 */
741
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
742
-		/** @var IShare[] $shares */
743
-		$shares = [];
744
-
745
-		//Get shares directly with this user
746
-		$qb = $this->dbConnection->getQueryBuilder();
747
-		$qb->select('*')
748
-			->from('share');
749
-
750
-		// Order by id
751
-		$qb->orderBy('id');
752
-
753
-		// Set limit and offset
754
-		if ($limit !== -1) {
755
-			$qb->setMaxResults($limit);
756
-		}
757
-		$qb->setFirstResult($offset);
758
-
759
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
760
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
761
-
762
-		// Filter by node if provided
763
-		if ($node !== null) {
764
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
765
-		}
766
-
767
-		$cursor = $qb->execute();
768
-
769
-		while($data = $cursor->fetch()) {
770
-			$shares[] = $this->createShareObject($data);
771
-		}
772
-		$cursor->closeCursor();
773
-
774
-
775
-		return $shares;
776
-	}
777
-
778
-	/**
779
-	 * Get a share by token
780
-	 *
781
-	 * @param string $token
782
-	 * @return IShare
783
-	 * @throws ShareNotFound
784
-	 */
785
-	public function getShareByToken($token) {
786
-		$qb = $this->dbConnection->getQueryBuilder();
787
-
788
-		$cursor = $qb->select('*')
789
-			->from('share')
790
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
791
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
792
-			->execute();
793
-
794
-		$data = $cursor->fetch();
795
-
796
-		if ($data === false) {
797
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
798
-		}
799
-
800
-		try {
801
-			$share = $this->createShareObject($data);
802
-		} catch (InvalidShare $e) {
803
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
804
-		}
805
-
806
-		return $share;
807
-	}
808
-
809
-	/**
810
-	 * get database row of a give share
811
-	 *
812
-	 * @param $id
813
-	 * @return array
814
-	 * @throws ShareNotFound
815
-	 */
816
-	private function getRawShare($id) {
817
-
818
-		// Now fetch the inserted share and create a complete share object
819
-		$qb = $this->dbConnection->getQueryBuilder();
820
-		$qb->select('*')
821
-			->from('share')
822
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
823
-
824
-		$cursor = $qb->execute();
825
-		$data = $cursor->fetch();
826
-		$cursor->closeCursor();
827
-
828
-		if ($data === false) {
829
-			throw new ShareNotFound;
830
-		}
831
-
832
-		return $data;
833
-	}
834
-
835
-	/**
836
-	 * Create a share object from an database row
837
-	 *
838
-	 * @param array $data
839
-	 * @return IShare
840
-	 * @throws InvalidShare
841
-	 * @throws ShareNotFound
842
-	 */
843
-	private function createShareObject($data) {
844
-
845
-		$share = new Share($this->rootFolder, $this->userManager);
846
-		$share->setId((int)$data['id'])
847
-			->setShareType((int)$data['share_type'])
848
-			->setPermissions((int)$data['permissions'])
849
-			->setTarget($data['file_target'])
850
-			->setMailSend((bool)$data['mail_send'])
851
-			->setToken($data['token']);
852
-
853
-		$shareTime = new \DateTime();
854
-		$shareTime->setTimestamp((int)$data['stime']);
855
-		$share->setShareTime($shareTime);
856
-		$share->setSharedWith($data['share_with']);
857
-
858
-		if ($data['uid_initiator'] !== null) {
859
-			$share->setShareOwner($data['uid_owner']);
860
-			$share->setSharedBy($data['uid_initiator']);
861
-		} else {
862
-			//OLD SHARE
863
-			$share->setSharedBy($data['uid_owner']);
864
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
865
-
866
-			$owner = $path->getOwner();
867
-			$share->setShareOwner($owner->getUID());
868
-		}
869
-
870
-		$share->setNodeId((int)$data['file_source']);
871
-		$share->setNodeType($data['item_type']);
872
-
873
-		$share->setProviderId($this->identifier());
874
-
875
-		return $share;
876
-	}
877
-
878
-	/**
879
-	 * Get the node with file $id for $user
880
-	 *
881
-	 * @param string $userId
882
-	 * @param int $id
883
-	 * @return \OCP\Files\File|\OCP\Files\Folder
884
-	 * @throws InvalidShare
885
-	 */
886
-	private function getNode($userId, $id) {
887
-		try {
888
-			$userFolder = $this->rootFolder->getUserFolder($userId);
889
-		} catch (NotFoundException $e) {
890
-			throw new InvalidShare();
891
-		}
892
-
893
-		$nodes = $userFolder->getById($id);
894
-
895
-		if (empty($nodes)) {
896
-			throw new InvalidShare();
897
-		}
898
-
899
-		return $nodes[0];
900
-	}
901
-
902
-	/**
903
-	 * A user is deleted from the system
904
-	 * So clean up the relevant shares.
905
-	 *
906
-	 * @param string $uid
907
-	 * @param int $shareType
908
-	 */
909
-	public function userDeleted($uid, $shareType) {
910
-		//TODO: probabaly a good idea to send unshare info to remote servers
911
-
912
-		$qb = $this->dbConnection->getQueryBuilder();
913
-
914
-		$qb->delete('share')
915
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
916
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
917
-			->execute();
918
-	}
919
-
920
-	/**
921
-	 * This provider does not handle groups
922
-	 *
923
-	 * @param string $gid
924
-	 */
925
-	public function groupDeleted($gid) {
926
-		// We don't handle groups here
927
-	}
928
-
929
-	/**
930
-	 * This provider does not handle groups
931
-	 *
932
-	 * @param string $uid
933
-	 * @param string $gid
934
-	 */
935
-	public function userDeletedFromGroup($uid, $gid) {
936
-		// We don't handle groups here
937
-	}
938
-
939
-	/**
940
-	 * check if users from other Nextcloud instances are allowed to mount public links share by this instance
941
-	 *
942
-	 * @return bool
943
-	 */
944
-	public function isOutgoingServer2serverShareEnabled() {
945
-		if ($this->gsConfig->onlyInternalFederation()) {
946
-			return false;
947
-		}
948
-		$result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
949
-		return ($result === 'yes');
950
-	}
951
-
952
-	/**
953
-	 * check if users are allowed to mount public links from other Nextclouds
954
-	 *
955
-	 * @return bool
956
-	 */
957
-	public function isIncomingServer2serverShareEnabled() {
958
-		if ($this->gsConfig->onlyInternalFederation()) {
959
-			return false;
960
-		}
961
-		$result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
962
-		return ($result === 'yes');
963
-	}
964
-
965
-	/**
966
-	 * Check if querying sharees on the lookup server is enabled
967
-	 *
968
-	 * @return bool
969
-	 */
970
-	public function isLookupServerQueriesEnabled() {
971
-		// in a global scale setup we should always query the lookup server
972
-		if ($this->gsConfig->isGlobalScaleEnabled()) {
973
-			return true;
974
-		}
975
-		$result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
976
-		return ($result === 'yes');
977
-	}
978
-
979
-
980
-	/**
981
-	 * Check if it is allowed to publish user specific data to the lookup server
982
-	 *
983
-	 * @return bool
984
-	 */
985
-	public function isLookupServerUploadEnabled() {
986
-		// in a global scale setup the admin is responsible to keep the lookup server up-to-date
987
-		if ($this->gsConfig->isGlobalScaleEnabled()) {
988
-			return false;
989
-		}
990
-		$result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes');
991
-		return ($result === 'yes');
992
-	}
993
-
994
-	/**
995
-	 * @inheritdoc
996
-	 */
997
-	public function getAccessList($nodes, $currentAccess) {
998
-		$ids = [];
999
-		foreach ($nodes as $node) {
1000
-			$ids[] = $node->getId();
1001
-		}
1002
-
1003
-		$qb = $this->dbConnection->getQueryBuilder();
1004
-		$qb->select('share_with', 'token', 'file_source')
1005
-			->from('share')
1006
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
1007
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1008
-			->andWhere($qb->expr()->orX(
1009
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1010
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1011
-			));
1012
-		$cursor = $qb->execute();
1013
-
1014
-		if ($currentAccess === false) {
1015
-			$remote = $cursor->fetch() !== false;
1016
-			$cursor->closeCursor();
1017
-
1018
-			return ['remote' => $remote];
1019
-		}
1020
-
1021
-		$remote = [];
1022
-		while ($row = $cursor->fetch()) {
1023
-			$remote[$row['share_with']] = [
1024
-				'node_id' => $row['file_source'],
1025
-				'token' => $row['token'],
1026
-			];
1027
-		}
1028
-		$cursor->closeCursor();
1029
-
1030
-		return ['remote' => $remote];
1031
-	}
477
+        return $share;
478
+    }
479
+
480
+    /**
481
+     * Get all children of this share
482
+     *
483
+     * @param IShare $parent
484
+     * @return IShare[]
485
+     */
486
+    public function getChildren(IShare $parent) {
487
+        $children = [];
488
+
489
+        $qb = $this->dbConnection->getQueryBuilder();
490
+        $qb->select('*')
491
+            ->from('share')
492
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
493
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
494
+            ->orderBy('id');
495
+
496
+        $cursor = $qb->execute();
497
+        while($data = $cursor->fetch()) {
498
+            $children[] = $this->createShareObject($data);
499
+        }
500
+        $cursor->closeCursor();
501
+
502
+        return $children;
503
+    }
504
+
505
+    /**
506
+     * Delete a share (owner unShares the file)
507
+     *
508
+     * @param IShare $share
509
+     */
510
+    public function delete(IShare $share) {
511
+
512
+        list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith());
513
+
514
+        $isOwner = false;
515
+
516
+        // if the local user is the owner we can send the unShare request directly...
517
+        if ($this->userManager->userExists($share->getShareOwner())) {
518
+            $this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
519
+            $this->revokeShare($share, true);
520
+        } else { // ... if not we need to correct ID for the unShare request
521
+            $remoteId = $this->getRemoteId($share);
522
+            $this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
523
+            $this->revokeShare($share, false);
524
+        }
525
+
526
+        // only remove the share when all messages are send to not lose information
527
+        // about the share to early
528
+        $this->removeShareFromTable($share);
529
+    }
530
+
531
+    /**
532
+     * in case of a re-share we need to send the other use (initiator or owner)
533
+     * a message that the file was unshared
534
+     *
535
+     * @param IShare $share
536
+     * @param bool $isOwner the user can either be the owner or the user who re-sahred it
537
+     * @throws ShareNotFound
538
+     * @throws \OC\HintException
539
+     */
540
+    protected function revokeShare($share, $isOwner) {
541
+        // also send a unShare request to the initiator, if this is a different user than the owner
542
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
543
+            if ($isOwner) {
544
+                list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
545
+            } else {
546
+                list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
547
+            }
548
+            $remoteId = $this->getRemoteId($share);
549
+            $this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
550
+        }
551
+    }
552
+
553
+    /**
554
+     * remove share from table
555
+     *
556
+     * @param IShare $share
557
+     */
558
+    public function removeShareFromTable(IShare $share) {
559
+        $this->removeShareFromTableById($share->getId());
560
+    }
561
+
562
+    /**
563
+     * remove share from table
564
+     *
565
+     * @param string $shareId
566
+     */
567
+    private function removeShareFromTableById($shareId) {
568
+        $qb = $this->dbConnection->getQueryBuilder();
569
+        $qb->delete('share')
570
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
571
+        $qb->execute();
572
+
573
+        $qb->delete('federated_reshares')
574
+            ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId)));
575
+        $qb->execute();
576
+    }
577
+
578
+    /**
579
+     * @inheritdoc
580
+     */
581
+    public function deleteFromSelf(IShare $share, $recipient) {
582
+        // nothing to do here. Technically deleteFromSelf in the context of federated
583
+        // shares is a umount of a external storage. This is handled here
584
+        // apps/files_sharing/lib/external/manager.php
585
+        // TODO move this code over to this app
586
+    }
587
+
588
+
589
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
590
+        $qb = $this->dbConnection->getQueryBuilder();
591
+        $qb->select('*')
592
+            ->from('share', 's')
593
+            ->andWhere($qb->expr()->orX(
594
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
595
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
596
+            ))
597
+            ->andWhere(
598
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))
599
+            );
600
+
601
+        /**
602
+         * Reshares for this user are shares where they are the owner.
603
+         */
604
+        if ($reshares === false) {
605
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
606
+        } else {
607
+            $qb->andWhere(
608
+                $qb->expr()->orX(
609
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
610
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
611
+                )
612
+            );
613
+        }
614
+
615
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
616
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
617
+
618
+        $qb->orderBy('id');
619
+
620
+        $cursor = $qb->execute();
621
+        $shares = [];
622
+        while ($data = $cursor->fetch()) {
623
+            $shares[$data['fileid']][] = $this->createShareObject($data);
624
+        }
625
+        $cursor->closeCursor();
626
+
627
+        return $shares;
628
+    }
629
+
630
+    /**
631
+     * @inheritdoc
632
+     */
633
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
634
+        $qb = $this->dbConnection->getQueryBuilder();
635
+        $qb->select('*')
636
+            ->from('share');
637
+
638
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
639
+
640
+        /**
641
+         * Reshares for this user are shares where they are the owner.
642
+         */
643
+        if ($reshares === false) {
644
+            //Special case for old shares created via the web UI
645
+            $or1 = $qb->expr()->andX(
646
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
647
+                $qb->expr()->isNull('uid_initiator')
648
+            );
649
+
650
+            $qb->andWhere(
651
+                $qb->expr()->orX(
652
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
653
+                    $or1
654
+                )
655
+            );
656
+        } else {
657
+            $qb->andWhere(
658
+                $qb->expr()->orX(
659
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
660
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
661
+                )
662
+            );
663
+        }
664
+
665
+        if ($node !== null) {
666
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
667
+        }
668
+
669
+        if ($limit !== -1) {
670
+            $qb->setMaxResults($limit);
671
+        }
672
+
673
+        $qb->setFirstResult($offset);
674
+        $qb->orderBy('id');
675
+
676
+        $cursor = $qb->execute();
677
+        $shares = [];
678
+        while($data = $cursor->fetch()) {
679
+            $shares[] = $this->createShareObject($data);
680
+        }
681
+        $cursor->closeCursor();
682
+
683
+        return $shares;
684
+    }
685
+
686
+    /**
687
+     * @inheritdoc
688
+     */
689
+    public function getShareById($id, $recipientId = null) {
690
+        $qb = $this->dbConnection->getQueryBuilder();
691
+
692
+        $qb->select('*')
693
+            ->from('share')
694
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
695
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
696
+
697
+        $cursor = $qb->execute();
698
+        $data = $cursor->fetch();
699
+        $cursor->closeCursor();
700
+
701
+        if ($data === false) {
702
+            throw new ShareNotFound('Can not find share with ID: ' . $id);
703
+        }
704
+
705
+        try {
706
+            $share = $this->createShareObject($data);
707
+        } catch (InvalidShare $e) {
708
+            throw new ShareNotFound();
709
+        }
710
+
711
+        return $share;
712
+    }
713
+
714
+    /**
715
+     * Get shares for a given path
716
+     *
717
+     * @param \OCP\Files\Node $path
718
+     * @return IShare[]
719
+     */
720
+    public function getSharesByPath(Node $path) {
721
+        $qb = $this->dbConnection->getQueryBuilder();
722
+
723
+        $cursor = $qb->select('*')
724
+            ->from('share')
725
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
726
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
727
+            ->execute();
728
+
729
+        $shares = [];
730
+        while($data = $cursor->fetch()) {
731
+            $shares[] = $this->createShareObject($data);
732
+        }
733
+        $cursor->closeCursor();
734
+
735
+        return $shares;
736
+    }
737
+
738
+    /**
739
+     * @inheritdoc
740
+     */
741
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
742
+        /** @var IShare[] $shares */
743
+        $shares = [];
744
+
745
+        //Get shares directly with this user
746
+        $qb = $this->dbConnection->getQueryBuilder();
747
+        $qb->select('*')
748
+            ->from('share');
749
+
750
+        // Order by id
751
+        $qb->orderBy('id');
752
+
753
+        // Set limit and offset
754
+        if ($limit !== -1) {
755
+            $qb->setMaxResults($limit);
756
+        }
757
+        $qb->setFirstResult($offset);
758
+
759
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
760
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
761
+
762
+        // Filter by node if provided
763
+        if ($node !== null) {
764
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
765
+        }
766
+
767
+        $cursor = $qb->execute();
768
+
769
+        while($data = $cursor->fetch()) {
770
+            $shares[] = $this->createShareObject($data);
771
+        }
772
+        $cursor->closeCursor();
773
+
774
+
775
+        return $shares;
776
+    }
777
+
778
+    /**
779
+     * Get a share by token
780
+     *
781
+     * @param string $token
782
+     * @return IShare
783
+     * @throws ShareNotFound
784
+     */
785
+    public function getShareByToken($token) {
786
+        $qb = $this->dbConnection->getQueryBuilder();
787
+
788
+        $cursor = $qb->select('*')
789
+            ->from('share')
790
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
791
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
792
+            ->execute();
793
+
794
+        $data = $cursor->fetch();
795
+
796
+        if ($data === false) {
797
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
798
+        }
799
+
800
+        try {
801
+            $share = $this->createShareObject($data);
802
+        } catch (InvalidShare $e) {
803
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
804
+        }
805
+
806
+        return $share;
807
+    }
808
+
809
+    /**
810
+     * get database row of a give share
811
+     *
812
+     * @param $id
813
+     * @return array
814
+     * @throws ShareNotFound
815
+     */
816
+    private function getRawShare($id) {
817
+
818
+        // Now fetch the inserted share and create a complete share object
819
+        $qb = $this->dbConnection->getQueryBuilder();
820
+        $qb->select('*')
821
+            ->from('share')
822
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
823
+
824
+        $cursor = $qb->execute();
825
+        $data = $cursor->fetch();
826
+        $cursor->closeCursor();
827
+
828
+        if ($data === false) {
829
+            throw new ShareNotFound;
830
+        }
831
+
832
+        return $data;
833
+    }
834
+
835
+    /**
836
+     * Create a share object from an database row
837
+     *
838
+     * @param array $data
839
+     * @return IShare
840
+     * @throws InvalidShare
841
+     * @throws ShareNotFound
842
+     */
843
+    private function createShareObject($data) {
844
+
845
+        $share = new Share($this->rootFolder, $this->userManager);
846
+        $share->setId((int)$data['id'])
847
+            ->setShareType((int)$data['share_type'])
848
+            ->setPermissions((int)$data['permissions'])
849
+            ->setTarget($data['file_target'])
850
+            ->setMailSend((bool)$data['mail_send'])
851
+            ->setToken($data['token']);
852
+
853
+        $shareTime = new \DateTime();
854
+        $shareTime->setTimestamp((int)$data['stime']);
855
+        $share->setShareTime($shareTime);
856
+        $share->setSharedWith($data['share_with']);
857
+
858
+        if ($data['uid_initiator'] !== null) {
859
+            $share->setShareOwner($data['uid_owner']);
860
+            $share->setSharedBy($data['uid_initiator']);
861
+        } else {
862
+            //OLD SHARE
863
+            $share->setSharedBy($data['uid_owner']);
864
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
865
+
866
+            $owner = $path->getOwner();
867
+            $share->setShareOwner($owner->getUID());
868
+        }
869
+
870
+        $share->setNodeId((int)$data['file_source']);
871
+        $share->setNodeType($data['item_type']);
872
+
873
+        $share->setProviderId($this->identifier());
874
+
875
+        return $share;
876
+    }
877
+
878
+    /**
879
+     * Get the node with file $id for $user
880
+     *
881
+     * @param string $userId
882
+     * @param int $id
883
+     * @return \OCP\Files\File|\OCP\Files\Folder
884
+     * @throws InvalidShare
885
+     */
886
+    private function getNode($userId, $id) {
887
+        try {
888
+            $userFolder = $this->rootFolder->getUserFolder($userId);
889
+        } catch (NotFoundException $e) {
890
+            throw new InvalidShare();
891
+        }
892
+
893
+        $nodes = $userFolder->getById($id);
894
+
895
+        if (empty($nodes)) {
896
+            throw new InvalidShare();
897
+        }
898
+
899
+        return $nodes[0];
900
+    }
901
+
902
+    /**
903
+     * A user is deleted from the system
904
+     * So clean up the relevant shares.
905
+     *
906
+     * @param string $uid
907
+     * @param int $shareType
908
+     */
909
+    public function userDeleted($uid, $shareType) {
910
+        //TODO: probabaly a good idea to send unshare info to remote servers
911
+
912
+        $qb = $this->dbConnection->getQueryBuilder();
913
+
914
+        $qb->delete('share')
915
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
916
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
917
+            ->execute();
918
+    }
919
+
920
+    /**
921
+     * This provider does not handle groups
922
+     *
923
+     * @param string $gid
924
+     */
925
+    public function groupDeleted($gid) {
926
+        // We don't handle groups here
927
+    }
928
+
929
+    /**
930
+     * This provider does not handle groups
931
+     *
932
+     * @param string $uid
933
+     * @param string $gid
934
+     */
935
+    public function userDeletedFromGroup($uid, $gid) {
936
+        // We don't handle groups here
937
+    }
938
+
939
+    /**
940
+     * check if users from other Nextcloud instances are allowed to mount public links share by this instance
941
+     *
942
+     * @return bool
943
+     */
944
+    public function isOutgoingServer2serverShareEnabled() {
945
+        if ($this->gsConfig->onlyInternalFederation()) {
946
+            return false;
947
+        }
948
+        $result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
949
+        return ($result === 'yes');
950
+    }
951
+
952
+    /**
953
+     * check if users are allowed to mount public links from other Nextclouds
954
+     *
955
+     * @return bool
956
+     */
957
+    public function isIncomingServer2serverShareEnabled() {
958
+        if ($this->gsConfig->onlyInternalFederation()) {
959
+            return false;
960
+        }
961
+        $result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
962
+        return ($result === 'yes');
963
+    }
964
+
965
+    /**
966
+     * Check if querying sharees on the lookup server is enabled
967
+     *
968
+     * @return bool
969
+     */
970
+    public function isLookupServerQueriesEnabled() {
971
+        // in a global scale setup we should always query the lookup server
972
+        if ($this->gsConfig->isGlobalScaleEnabled()) {
973
+            return true;
974
+        }
975
+        $result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
976
+        return ($result === 'yes');
977
+    }
978
+
979
+
980
+    /**
981
+     * Check if it is allowed to publish user specific data to the lookup server
982
+     *
983
+     * @return bool
984
+     */
985
+    public function isLookupServerUploadEnabled() {
986
+        // in a global scale setup the admin is responsible to keep the lookup server up-to-date
987
+        if ($this->gsConfig->isGlobalScaleEnabled()) {
988
+            return false;
989
+        }
990
+        $result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes');
991
+        return ($result === 'yes');
992
+    }
993
+
994
+    /**
995
+     * @inheritdoc
996
+     */
997
+    public function getAccessList($nodes, $currentAccess) {
998
+        $ids = [];
999
+        foreach ($nodes as $node) {
1000
+            $ids[] = $node->getId();
1001
+        }
1002
+
1003
+        $qb = $this->dbConnection->getQueryBuilder();
1004
+        $qb->select('share_with', 'token', 'file_source')
1005
+            ->from('share')
1006
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
1007
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1008
+            ->andWhere($qb->expr()->orX(
1009
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1010
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1011
+            ));
1012
+        $cursor = $qb->execute();
1013
+
1014
+        if ($currentAccess === false) {
1015
+            $remote = $cursor->fetch() !== false;
1016
+            $cursor->closeCursor();
1017
+
1018
+            return ['remote' => $remote];
1019
+        }
1020
+
1021
+        $remote = [];
1022
+        while ($row = $cursor->fetch()) {
1023
+            $remote[$row['share_with']] = [
1024
+                'node_id' => $row['file_source'],
1025
+                'token' => $row['token'],
1026
+            ];
1027
+        }
1028
+        $cursor->closeCursor();
1029
+
1030
+        return ['remote' => $remote];
1031
+    }
1032 1032
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -192,7 +192,7 @@  discard block
 block discarded – undo
192 192
 		if ($remoteShare) {
193 193
 			try {
194 194
 				$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
195
-				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time());
195
+				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_'.time());
196 196
 				$share->setId($shareId);
197 197
 				list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
198 198
 				// remote share was create successfully if we get a valid token as return
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 			$failure = true;
273 273
 		}
274 274
 
275
-		if($failure) {
275
+		if ($failure) {
276 276
 			$this->removeShareFromTableById($shareId);
277 277
 			$message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate.',
278 278
 				[$share->getNode()->getName(), $share->getSharedWith()]);
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
 			->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
325 325
 		$result = $query->execute()->fetchAll();
326 326
 
327
-		if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
327
+		if (isset($result[0]) && (int) $result[0]['remote_id'] > 0) {
328 328
 			return $result[0];
329 329
 		}
330 330
 
@@ -366,7 +366,7 @@  discard block
 block discarded – undo
366 366
 		$qb->execute();
367 367
 		$id = $qb->getLastInsertId();
368 368
 
369
-		return (int)$id;
369
+		return (int) $id;
370 370
 	}
371 371
 
372 372
 	/**
@@ -456,14 +456,14 @@  discard block
 block discarded – undo
456 456
 	public function getRemoteId(IShare $share) {
457 457
 		$query = $this->dbConnection->getQueryBuilder();
458 458
 		$query->select('remote_id')->from('federated_reshares')
459
-			->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
459
+			->where($query->expr()->eq('share_id', $query->createNamedParameter((int) $share->getId())));
460 460
 		$data = $query->execute()->fetch();
461 461
 
462 462
 		if (!is_array($data) || !isset($data['remote_id'])) {
463 463
 			throw new ShareNotFound();
464 464
 		}
465 465
 
466
-		return (int)$data['remote_id'];
466
+		return (int) $data['remote_id'];
467 467
 	}
468 468
 
469 469
 	/**
@@ -494,7 +494,7 @@  discard block
 block discarded – undo
494 494
 			->orderBy('id');
495 495
 
496 496
 		$cursor = $qb->execute();
497
-		while($data = $cursor->fetch()) {
497
+		while ($data = $cursor->fetch()) {
498 498
 			$children[] = $this->createShareObject($data);
499 499
 		}
500 500
 		$cursor->closeCursor();
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
 			);
613 613
 		}
614 614
 
615
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
615
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
616 616
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
617 617
 
618 618
 		$qb->orderBy('id');
@@ -675,7 +675,7 @@  discard block
 block discarded – undo
675 675
 
676 676
 		$cursor = $qb->execute();
677 677
 		$shares = [];
678
-		while($data = $cursor->fetch()) {
678
+		while ($data = $cursor->fetch()) {
679 679
 			$shares[] = $this->createShareObject($data);
680 680
 		}
681 681
 		$cursor->closeCursor();
@@ -699,7 +699,7 @@  discard block
 block discarded – undo
699 699
 		$cursor->closeCursor();
700 700
 
701 701
 		if ($data === false) {
702
-			throw new ShareNotFound('Can not find share with ID: ' . $id);
702
+			throw new ShareNotFound('Can not find share with ID: '.$id);
703 703
 		}
704 704
 
705 705
 		try {
@@ -727,7 +727,7 @@  discard block
 block discarded – undo
727 727
 			->execute();
728 728
 
729 729
 		$shares = [];
730
-		while($data = $cursor->fetch()) {
730
+		while ($data = $cursor->fetch()) {
731 731
 			$shares[] = $this->createShareObject($data);
732 732
 		}
733 733
 		$cursor->closeCursor();
@@ -766,7 +766,7 @@  discard block
 block discarded – undo
766 766
 
767 767
 		$cursor = $qb->execute();
768 768
 
769
-		while($data = $cursor->fetch()) {
769
+		while ($data = $cursor->fetch()) {
770 770
 			$shares[] = $this->createShareObject($data);
771 771
 		}
772 772
 		$cursor->closeCursor();
@@ -843,15 +843,15 @@  discard block
 block discarded – undo
843 843
 	private function createShareObject($data) {
844 844
 
845 845
 		$share = new Share($this->rootFolder, $this->userManager);
846
-		$share->setId((int)$data['id'])
847
-			->setShareType((int)$data['share_type'])
848
-			->setPermissions((int)$data['permissions'])
846
+		$share->setId((int) $data['id'])
847
+			->setShareType((int) $data['share_type'])
848
+			->setPermissions((int) $data['permissions'])
849 849
 			->setTarget($data['file_target'])
850
-			->setMailSend((bool)$data['mail_send'])
850
+			->setMailSend((bool) $data['mail_send'])
851 851
 			->setToken($data['token']);
852 852
 
853 853
 		$shareTime = new \DateTime();
854
-		$shareTime->setTimestamp((int)$data['stime']);
854
+		$shareTime->setTimestamp((int) $data['stime']);
855 855
 		$share->setShareTime($shareTime);
856 856
 		$share->setSharedWith($data['share_with']);
857 857
 
@@ -861,13 +861,13 @@  discard block
 block discarded – undo
861 861
 		} else {
862 862
 			//OLD SHARE
863 863
 			$share->setSharedBy($data['uid_owner']);
864
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
864
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
865 865
 
866 866
 			$owner = $path->getOwner();
867 867
 			$share->setShareOwner($owner->getUID());
868 868
 		}
869 869
 
870
-		$share->setNodeId((int)$data['file_source']);
870
+		$share->setNodeId((int) $data['file_source']);
871 871
 		$share->setNodeType($data['item_type']);
872 872
 
873 873
 		$share->setProviderId($this->identifier());
Please login to merge, or discard this patch.
lib/public/Federation/ICloudFederationProvider.php 1 patch
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -39,42 +39,42 @@
 block discarded – undo
39 39
 
40 40
 interface ICloudFederationProvider {
41 41
 
42
-	/**
43
-	 * get the name of the share type, handled by this provider
44
-	 *
45
-	 * @return string
46
-	 *
47
-	 * @since 14.0.0
48
-	 */
49
-	public function getShareType();
42
+    /**
43
+     * get the name of the share type, handled by this provider
44
+     *
45
+     * @return string
46
+     *
47
+     * @since 14.0.0
48
+     */
49
+    public function getShareType();
50 50
 
51
-	/**
52
-	 * share received from another server
53
-	 *
54
-	 * @param ICloudFederationShare $share
55
-	 * @return string provider specific unique ID of the share
56
-	 *
57
-	 * @throws ProviderCouldNotAddShareException
58
-	 *
59
-	 * @since 14.0.0
60
-	 */
61
-	public function shareReceived(ICloudFederationShare $share);
51
+    /**
52
+     * share received from another server
53
+     *
54
+     * @param ICloudFederationShare $share
55
+     * @return string provider specific unique ID of the share
56
+     *
57
+     * @throws ProviderCouldNotAddShareException
58
+     *
59
+     * @since 14.0.0
60
+     */
61
+    public function shareReceived(ICloudFederationShare $share);
62 62
 
63
-	/**
64
-	 * notification received from another server
65
-	 *
66
-	 * @param string $notificationType (e.g SHARE_ACCEPTED)
67
-	 * @param string $providerId share ID
68
-	 * @param array $notification provider specific notification
69
-	 * @return array $data send back to sender
70
-	 *
71
-	 * @throws ShareNotFound
72
-	 * @throws ActionNotSupportedException
73
-	 * @throws BadRequestException
74
-	 * @throws AuthenticationFailedException
75
-	 *
76
-	 * @since 14.0.0
77
-	 */
78
-	public function notificationReceived($notificationType, $providerId, array $notification);
63
+    /**
64
+     * notification received from another server
65
+     *
66
+     * @param string $notificationType (e.g SHARE_ACCEPTED)
67
+     * @param string $providerId share ID
68
+     * @param array $notification provider specific notification
69
+     * @return array $data send back to sender
70
+     *
71
+     * @throws ShareNotFound
72
+     * @throws ActionNotSupportedException
73
+     * @throws BadRequestException
74
+     * @throws AuthenticationFailedException
75
+     *
76
+     * @since 14.0.0
77
+     */
78
+    public function notificationReceived($notificationType, $providerId, array $notification);
79 79
 
80 80
 }
Please login to merge, or discard this patch.