Completed
Pull Request — master (#32303)
by Victor
10:05
created

RequestHandlerController::reShare()   A

Complexity

Conditions 3
Paths 17

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 17
nop 1
dl 0
loc 50
rs 9.0909
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\IRequest;
40
use OCP\IUserManager;
41
42
/**
43
 * Class RequestHandlerController
44
 *
45
 * Handles OCS Request to the federated share API
46
 *
47
 * @package OCA\FederatedFileSharing\API
48
 */
49
class RequestHandlerController extends OCSController {
50
51
	/** @var OcmMiddleware */
52
	private $ocmMiddleware;
53
54
	/** @var IUserManager */
55
	private $userManager;
56
57
	/** @var AddressHandler */
58
	private $addressHandler;
59
60
	/** @var  FedShareManager */
61
	private $fedShareManager;
62
63
	/**
64
	 * Server2Server constructor.
65
	 *
66
	 * @param string $appName
67
	 * @param IRequest $request
68
	 * @param OcmMiddleware $ocmMiddleware
69
	 * @param IUserManager $userManager
70
	 * @param AddressHandler $addressHandler
71
	 * @param FedShareManager $fedShareManager
72
	 */
73
	public function __construct($appName,
74
								IRequest $request,
75
								OcmMiddleware $ocmMiddleware,
76
								IUserManager $userManager,
77
								AddressHandler $addressHandler,
78
								FedShareManager $fedShareManager
79
	) {
80
		parent::__construct($appName, $request);
81
82
		$this->ocmMiddleware = $ocmMiddleware;
83
		$this->userManager = $userManager;
84
		$this->addressHandler = $addressHandler;
85
		$this->fedShareManager = $fedShareManager;
86
	}
87
88
	/**
89
	 * @NoCSRFRequired
90
	 * @PublicPage
91
	 *
92
	 * create a new share
93
	 *
94
	 * @return Result
95
	 */
96
	public function createShare() {
97
		try {
98
			$this->ocmMiddleware->assertIncomingSharingEnabled();
99
			$remote = $this->request->getParam('remote', null);
100
			$token = $this->request->getParam('token', null);
101
			$name = $this->request->getParam('name', null);
102
			$owner = $this->request->getParam('owner', null);
103
			$sharedBy = $this->request->getParam('sharedBy', null);
104
			$shareWith = $this->request->getParam('shareWith', null);
105
			$remoteId = $this->request->getParam('remoteId', null);
106
			$sharedByFederatedId = $this->request->getParam(
107
				'sharedByFederatedId',
108
				null
109
			);
110
			$ownerFederatedId = $this->request->getParam('ownerFederatedId', null);
111
			$this->ocmMiddleware->assertNotNull(
112
				[
113
					'remote' => $remote,
114
					'token' => $token,
115
					'name' => $name,
116
					'owner' => $owner,
117
					'remoteId' => $remoteId,
118
					'shareWith' => $shareWith
119
				]
120
			);
121
122
			if (!\OCP\Util::isValidFileName($name)) {
123
				throw new BadRequestException(
124
					'The mountpoint name contains invalid characters.'
125
				);
126
			}
127
			// FIXME this should be a method in the user management instead
128
			\OCP\Util::writeLog('files_sharing', 'shareWith before, ' . $shareWith, \OCP\Util::DEBUG);
129
			\OCP\Util::emitHook(
130
				'\OCA\Files_Sharing\API\Server2Server',
131
				'preLoginNameUsedAsUserName',
132
				['uid' => &$shareWith]
133
			);
134
			\OCP\Util::writeLog('files_sharing', 'shareWith after, ' . $shareWith, \OCP\Util::DEBUG);
135
			if (!$this->userManager->userExists($shareWith)) {
136
				throw new BadRequestException('User does not exist');
137
			}
138
139
			$ownerAddress = $ownerFederatedId === null
140
				? new Address("{$owner}@{$remote}")
141
				: new Address($ownerFederatedId);
142
			// if the owner of the share and the initiator are the same user
143
			// we also complete the federated share ID for the initiator
144
			if ($sharedByFederatedId === null && $owner === $sharedBy) {
145
				$sharedByFederatedId = $ownerAddress->getCloudId();
146
			}
147
148
			$sharedByAddress = new Address($sharedByFederatedId);
149
150
			$this->fedShareManager->createShare(
151
				$ownerAddress,
152
				$sharedByAddress,
153
				$shareWith,
154
				$remoteId,
155
				$name,
156
				$token
157
			);
158
		} catch (OcmException $e) {
159
			return new Result(
160
				null,
161
				$e->getHttpStatusCode(),
162
				$e->getMessage()
163
			);
164
		} catch (\Exception $e) {
165
			\OCP\Util::writeLog(
166
				'files_sharing',
167
				'server can not add remote share, ' . $e->getMessage(),
168
				\OCP\Util::ERROR
169
			);
170
			return new Result(
171
				null,
172
				Http::STATUS_INTERNAL_SERVER_ERROR,
173
				'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...
174
			);
175
		}
176
		return new Result();
177
	}
178
179
	/**
180
	 * @NoCSRFRequired
181
	 * @PublicPage
182
	 *
183
	 * create re-share on behalf of another user
184
	 *
185
	 * @param int $id
186
	 *
187
	 * @return Result
188
	 */
189
	public function reShare($id) {
190
		$token = $this->request->getParam('token', null);
191
		$shareWith = $this->request->getParam('shareWith', null);
192
		$permission = $this->request->getParam('permission', null);
193
		$remoteId = $this->request->getParam('remoteId', null);
194
195
		try {
196
			$this->ocmMiddleware->assertNotNull(
197
				[
198
					'id' => $id,
199
					'token' => $token,
200
					'shareWith' => $shareWith,
201
					'permission'  => $permission,
202
					'remoteId' => $remoteId
203
				]
204
			);
205
			$permission = (int) $permission;
206
			$remoteId = (int) $remoteId;
207
			$share = $this->ocmMiddleware->getValidShare($id, $token);
208
209
			// don't allow to share a file back to the owner
210
			$owner = $share->getShareOwner();
211
			$ownerAddress = $this->addressHandler->getLocalUserFederatedAddress($owner);
212
			$shareWithAddress = new Address($shareWith);
213
			$this->ocmMiddleware->assertNotSameUser($ownerAddress, $shareWithAddress);
214
215
			$this->ocmMiddleware->assertSharingPermissionSet($share);
216
			$result = $this->fedShareManager->reShare(
217
				$share,
218
				$remoteId,
219
				$shareWith,
220
				$permission
221
			);
222
		} catch (OcmException $e) {
223
			return new Result(
224
				null,
225
				$e->getHttpStatusCode(),
226
				$e->getMessage()
227
			);
228
		} catch (\Exception $e) {
229
			return new Result(null, Http::STATUS_BAD_REQUEST);
230
		}
231
232
		return new Result(
233
			[
234
				'token' => $result->getToken(),
235
				'remoteId' => $result->getId()
236
			]
237
		);
238
	}
239
240
	/**
241
	 * @NoCSRFRequired
242
	 * @PublicPage
243
	 *
244
	 * accept server-to-server share
245
	 *
246
	 * @param int $id
247
	 *
248
	 * @return Result
249
	 */
250 View Code Duplication
	public function acceptShare($id) {
251
		try {
252
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
253
			$token = $this->request->getParam('token', null);
254
			$share = $this->ocmMiddleware->getValidShare($id, $token);
255
			$this->fedShareManager->acceptShare($share);
256
		} catch (NotImplementedException $e) {
257
			return new Result(
258
				null,
259
				Http::STATUS_SERVICE_UNAVAILABLE,
260
				'Server does not support federated cloud sharing'
261
			);
262
		}
263
		return new Result();
264
	}
265
266
	/**
267
	 * @NoCSRFRequired
268
	 * @PublicPage
269
	 *
270
	 * decline server-to-server share
271
	 *
272
	 * @param int $id
273
	 *
274
	 * @return Result
275
	 */
276 View Code Duplication
	public function declineShare($id) {
277
		try {
278
			$token = $this->request->getParam('token', null);
279
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
280
			$share = $this->ocmMiddleware->getValidShare($id, $token);
281
			$this->fedShareManager->declineShare($share);
282
		} catch (NotImplementedException $e) {
283
			return new Result(
284
				null,
285
				Http::STATUS_SERVICE_UNAVAILABLE,
286
				'Server does not support federated cloud sharing'
287
			);
288
		}
289
290
		return new Result();
291
	}
292
293
	/**
294
	 * @NoCSRFRequired
295
	 * @PublicPage
296
	 *
297
	 * remove server-to-server share if it was unshared by the owner
298
	 *
299
	 * @param int $id
300
	 *
301
	 * @return Result
302
	 */
303 View Code Duplication
	public function unshare($id) {
304
		try {
305
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
306
			$token = $this->request->getParam('token', null);
307
			if ($token && $id) {
308
				$this->fedShareManager->unshare($id, $token);
309
			}
310
		} catch (NotImplementedException $e) {
311
			return new Result(
312
				null,
313
				Http::STATUS_SERVICE_UNAVAILABLE,
314
				'Server does not support federated cloud sharing'
315
			);
316
		} catch (\Exception $e) {
317
			// pass
318
		}
319
		return new Result();
320
	}
321
322
	/**
323
	 * @NoCSRFRequired
324
	 * @PublicPage
325
	 *
326
	 * federated share was revoked, either by the owner or the re-sharer
327
	 *
328
	 * @param int $id
329
	 *
330
	 * @return Result
331
	 */
332 View Code Duplication
	public function revoke($id) {
333
		try {
334
			$token = $this->request->getParam('token', null);
335
			$share = $this->ocmMiddleware->getValidShare($id, $token);
336
			$this->fedShareManager->undoReshare($share);
337
		} catch (\Exception $e) {
338
			return new Result(null, Http::STATUS_BAD_REQUEST);
339
		}
340
341
		return new Result();
342
	}
343
344
	/**
345
	 * @NoCSRFRequired
346
	 * @PublicPage
347
	 *
348
	 * update share information to keep federated re-shares in sync
349
	 *
350
	 * @param int $id
351
	 *
352
	 * @return Result
353
	 */
354
	public function updatePermissions($id) {
355
		try {
356
			$permissions = $this->request->getParam('permissions', null);
357
			$token = $this->request->getParam('token', null);
358
			$share = $this->ocmMiddleware->getValidShare($id, $token);
359
			$validPermission = \ctype_digit((string)$permissions);
360
			if (!$validPermission) {
361
				throw new \Exception();
362
			}
363
			$this->fedShareManager->updatePermissions($share, (int)$permissions);
364
		} catch (\Exception $e) {
365
			return new Result(null, Http::STATUS_BAD_REQUEST);
366
		}
367
368
		return new Result();
369
	}
370
}
371