Completed
Pull Request — master (#32303)
by Victor
12:09
created

RequestHandlerController::assertIncomingSharingEnabled()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Arthur Schiwon <[email protected]>
4
 * @author Björn Schießle <[email protected]>
5
 * @author Joas Schilling <[email protected]>
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Morris Jobke <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 *
10
 * @copyright Copyright (c) 2018, ownCloud GmbH
11
 * @license AGPL-3.0
12
 *
13
 * This code is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License, version 3,
15
 * as published by the Free Software Foundation.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License, version 3,
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
24
 *
25
 */
26
27
namespace OCA\FederatedFileSharing\Controller;
28
29
use OC\OCS\Result;
30
use OCA\FederatedFileSharing\Address;
31
use OCA\FederatedFileSharing\AddressHandler;
32
use OCA\FederatedFileSharing\FedShareManager;
33
use OCA\FederatedFileSharing\Middleware\OcmMiddleware;
34
use OCA\FederatedFileSharing\Ocm\Exception\BadRequestException;
35
use OCA\FederatedFileSharing\Ocm\Exception\NotImplementedException;
36
use OCA\FederatedFileSharing\Ocm\Exception\OcmException;
37
use OCP\AppFramework\Http;
38
use OCP\AppFramework\OCSController;
39
use OCP\Constants;
40
use OCP\IRequest;
41
use OCP\IUserManager;
42
use OCP\Share\IShare;
43
44
/**
45
 * Class RequestHandlerController
46
 *
47
 * Handles OCS Request to the federated share API
48
 *
49
 * @package OCA\FederatedFileSharing\API
50
 */
51
class RequestHandlerController extends OCSController {
52
53
	/** @var OcmMiddleware */
54
	private $ocmMiddleware;
55
56
	/** @var IUserManager */
57
	private $userManager;
58
59
	/** @var AddressHandler */
60
	private $addressHandler;
61
62
	/** @var  FedShareManager */
63
	private $fedShareManager;
64
65
	/**
66
	 * Server2Server constructor.
67
	 *
68
	 * @param string $appName
69
	 * @param IRequest $request
70
	 * @param OcmMiddleware $ocmMiddleware
71
	 * @param IUserManager $userManager
72
	 * @param AddressHandler $addressHandler
73
	 * @param FedShareManager $fedShareManager
74
	 */
75
	public function __construct($appName,
76
								IRequest $request,
77
								OcmMiddleware $ocmMiddleware,
78
								IUserManager $userManager,
79
								AddressHandler $addressHandler,
80
								FedShareManager $fedShareManager
81
	) {
82
		parent::__construct($appName, $request);
83
84
		$this->ocmMiddleware = $ocmMiddleware;
85
		$this->userManager = $userManager;
86
		$this->addressHandler = $addressHandler;
87
		$this->fedShareManager = $fedShareManager;
88
	}
89
90
	/**
91
	 * @NoCSRFRequired
92
	 * @PublicPage
93
	 *
94
	 * create a new share
95
	 *
96
	 * @return Result
97
	 */
98
	public function createShare() {
99
		try {
100
			$this->ocmMiddleware->assertIncomingSharingEnabled();
101
			$remote = $this->request->getParam('remote', null);
102
			$token = $this->request->getParam('token', null);
103
			$name = $this->request->getParam('name', null);
104
			$owner = $this->request->getParam('owner', null);
105
			$sharedBy = $this->request->getParam('sharedBy', null);
106
			$shareWith = $this->request->getParam('shareWith', null);
107
			$remoteId = $this->request->getParam('remoteId', null);
108
			$sharedByFederatedId = $this->request->getParam(
109
				'sharedByFederatedId',
110
				null
111
			);
112
			$ownerFederatedId = $this->request->getParam('ownerFederatedId', null);
113
			$this->ocmMiddleware->assertNotNull(
114
				[
115
					'remote' => $remote,
116
					'token' => $token,
117
					'name' => $name,
118
					'owner' => $owner,
119
					'remoteId' => $remoteId,
120
					'shareWith' => $shareWith
121
				]
122
			);
123
124
			if (!\OCP\Util::isValidFileName($name)) {
125
				throw new BadRequestException(
126
					'The mountpoint name contains invalid characters.'
127
				);
128
			}
129
			// FIXME this should be a method in the user management instead
130
			\OCP\Util::writeLog('files_sharing', 'shareWith before, ' . $shareWith, \OCP\Util::DEBUG);
131
			\OCP\Util::emitHook(
132
				'\OCA\Files_Sharing\API\Server2Server',
133
				'preLoginNameUsedAsUserName',
134
				['uid' => &$shareWith]
135
			);
136
			\OCP\Util::writeLog('files_sharing', 'shareWith after, ' . $shareWith, \OCP\Util::DEBUG);
137
			if (!$this->userManager->userExists($shareWith)) {
138
				throw new BadRequestException('User does not exist');
139
			}
140
141
			if ($ownerFederatedId === null) {
142
				$ownerFederatedId = $owner . '@' . $this->addressHandler->normalizeRemote($remote);
143
			}
144
			// if the owner of the share and the initiator are the same user
145
			// we also complete the federated share ID for the initiator
146
			if ($sharedByFederatedId === null && $owner === $sharedBy) {
147
				$sharedByFederatedId = $ownerFederatedId;
148
			}
149
150
			$ownerAddress = new Address($ownerFederatedId);
151
			$sharedByAddress = new Address($sharedByFederatedId);
152
153
			$this->fedShareManager->createShare(
154
				$ownerAddress,
155
				$sharedByAddress,
156
				$shareWith,
157
				$remoteId,
158
				$name,
159
				$token
160
			);
161
		} catch (OcmException $e) {
162
			return new Result(
163
				null,
164
				$e->getHttpStatusCode(),
165
				$e->getMessage()
166
			);
167
		} catch (\Exception $e) {
168
			\OCP\Util::writeLog(
169
				'files_sharing',
170
				'server can not add remote share, ' . $e->getMessage(),
171
				\OCP\Util::ERROR
172
			);
173
			return new Result(
174
				null,
175
				Http::STATUS_INTERNAL_SERVER_ERROR,
176
				'internal server error, was not able to add share from ' . $remote
0 ignored issues
show
Bug introduced by
The variable $remote does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
177
			);
178
		}
179
		return new Result();
180
	}
181
182
	/**
183
	 * @NoCSRFRequired
184
	 * @PublicPage
185
	 *
186
	 * create re-share on behalf of another user
187
	 *
188
	 * @param int $id
189
	 *
190
	 * @return Result
191
	 */
192
	public function reShare($id) {
193
		$token = $this->request->getParam('token', null);
194
		$shareWith = $this->request->getParam('shareWith', null);
195
		$permission = $this->request->getParam('permission', null);
196
		$remoteId = $this->request->getParam('remoteId', null);
197
198
		try {
199
			$this->ocmMiddleware->assertNotNull(
200
				[
201
					'id' => $id,
202
					'token' => $token,
203
					'shareWith' => $shareWith,
204
					'permission'  => $permission,
205
					'remoteId' => $remoteId
206
				]
207
			);
208
			$permission = (int) $permission;
209
			$remoteId = (int) $remoteId;
210
			$share = $this->ocmMiddleware->getValidShare($id, $token);
211
212
			// don't allow to share a file back to the owner
213
			list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
214
			$owner = $share->getShareOwner();
215
			$currentServer = $this->addressHandler->generateRemoteURL();
216
			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
217
				return new Result(null, Http::STATUS_FORBIDDEN);
218
			}
219
220
			$reSharingAllowed = $share->getPermissions() & Constants::PERMISSION_SHARE;
221
			if (!$reSharingAllowed) {
222
				return new Result(null, Http::STATUS_BAD_REQUEST);
223
			}
224
			$result = $this->fedShareManager->reShare(
225
				$share,
226
				$remoteId,
227
				$shareWith,
228
				$permission
229
			);
230
		} catch (OcmException $e) {
231
			return new Result(
232
				null,
233
				$e->getHttpStatusCode(),
234
				$e->getMessage()
235
			);
236
		} catch (\Exception $e) {
237
			return new Result(null, Http::STATUS_BAD_REQUEST);
238
		}
239
240
		return new Result(
241
			[
242
				'token' => $result->getToken(),
243
				'remoteId' => $result->getId()
244
			]
245
		);
246
	}
247
248
	/**
249
	 * @NoCSRFRequired
250
	 * @PublicPage
251
	 *
252
	 * accept server-to-server share
253
	 *
254
	 * @param int $id
255
	 *
256
	 * @return Result
257
	 */
258 View Code Duplication
	public function acceptShare($id) {
259
		try {
260
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
261
			$token = $this->request->getParam('token', null);
262
			$share = $this->ocmMiddleware->getValidShare($id, $token);
263
			$this->fedShareManager->acceptShare($share);
264
		} catch (NotImplementedException $e) {
265
			return new Result(
266
				null,
267
				Http::STATUS_SERVICE_UNAVAILABLE,
268
				'Server does not support federated cloud sharing'
269
			);
270
		}
271
		return new Result();
272
	}
273
274
	/**
275
	 * @NoCSRFRequired
276
	 * @PublicPage
277
	 *
278
	 * decline server-to-server share
279
	 *
280
	 * @param int $id
281
	 *
282
	 * @return Result
283
	 */
284 View Code Duplication
	public function declineShare($id) {
285
		try {
286
			$token = $this->request->getParam('token', null);
287
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
288
			$share = $this->ocmMiddleware->getValidShare($id, $token);
289
			$this->fedShareManager->declineShare($share);
290
		} catch (NotImplementedException $e) {
291
			return new Result(
292
				null,
293
				Http::STATUS_SERVICE_UNAVAILABLE,
294
				'Server does not support federated cloud sharing'
295
			);
296
		}
297
298
		return new Result();
299
	}
300
301
	/**
302
	 * @NoCSRFRequired
303
	 * @PublicPage
304
	 *
305
	 * remove server-to-server share if it was unshared by the owner
306
	 *
307
	 * @param int $id
308
	 *
309
	 * @return Result
310
	 */
311 View Code Duplication
	public function unshare($id) {
312
		try {
313
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
314
			$token = $this->request->getParam('token', null);
315
			if ($token && $id) {
316
				$this->fedShareManager->unshare($id, $token);
317
			}
318
		} catch (NotImplementedException $e) {
319
			return new Result(
320
				null,
321
				Http::STATUS_SERVICE_UNAVAILABLE,
322
				'Server does not support federated cloud sharing'
323
			);
324
		} catch (\Exception $e) {
325
			// pass
326
		}
327
		return new Result();
328
	}
329
330
	/**
331
	 * @NoCSRFRequired
332
	 * @PublicPage
333
	 *
334
	 * federated share was revoked, either by the owner or the re-sharer
335
	 *
336
	 * @param int $id
337
	 *
338
	 * @return Result
339
	 */
340 View Code Duplication
	public function revoke($id) {
341
		try {
342
			$token = $this->request->getParam('token', null);
343
			$share = $this->getValidShare($id, $token);
344
			$this->fedShareManager->revoke($share);
345
		} catch (\Exception $e) {
346
			return new Result(null, Http::STATUS_BAD_REQUEST);
347
		}
348
349
		return new Result();
350
	}
351
352
	/**
353
	 * @NoCSRFRequired
354
	 * @PublicPage
355
	 *
356
	 * update share information to keep federated re-shares in sync
357
	 *
358
	 * @param int $id
359
	 *
360
	 * @return Result
361
	 */
362
	public function updatePermissions($id) {
363
		try {
364
			$permissions = $this->request->getParam('permissions', null);
365
			$token = $this->request->getParam('token', null);
366
			$share = $this->ocmMiddleware->getValidShare($id, $token);
367
			$validPermission = \ctype_digit((string)$permissions);
368
			if (!$validPermission) {
369
				throw new \Exception();
370
			}
371
			$this->fedShareManager->updatePermissions($share, (int)$permissions);
372
		} catch (\Exception $e) {
373
			return new Result(null, Http::STATUS_BAD_REQUEST);
374
		}
375
376
		return new Result();
377
	}
378
}
379