Completed
Pull Request — master (#32303)
by Victor
13:13 queued 03:56
created

RequestHandlerController::reShare()   A

Complexity

Conditions 3
Paths 19

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 19
nop 1
dl 0
loc 52
rs 9.0472
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 = $this->ocmMiddleware->normalizePermissions(
206
				(int) $permission
207
			);
208
			$remoteId = (int) $remoteId;
209
			$share = $this->ocmMiddleware->getValidShare($id, $token);
210
211
			// don't allow to share a file back to the owner
212
			$owner = $share->getShareOwner();
213
			$ownerAddress = $this->addressHandler->getLocalUserFederatedAddress($owner);
214
			$shareWithAddress = new Address($shareWith);
215
			$this->ocmMiddleware->assertNotSameUser($ownerAddress, $shareWithAddress);
216
217
			$this->ocmMiddleware->assertSharingPermissionSet($share);
218
			$result = $this->fedShareManager->reShare(
219
				$share,
220
				$remoteId,
221
				$shareWith,
222
				$permission
223
			);
224
		} catch (OcmException $e) {
225
			return new Result(
226
				null,
227
				$e->getHttpStatusCode(),
228
				$e->getMessage()
229
			);
230
		} catch (\Exception $e) {
231
			return new Result(null, Http::STATUS_BAD_REQUEST);
232
		}
233
234
		return new Result(
235
			[
236
				'token' => $result->getToken(),
237
				'remoteId' => $result->getId()
238
			]
239
		);
240
	}
241
242
	/**
243
	 * @NoCSRFRequired
244
	 * @PublicPage
245
	 *
246
	 * accept server-to-server share
247
	 *
248
	 * @param int $id
249
	 *
250
	 * @return Result
251
	 */
252 View Code Duplication
	public function acceptShare($id) {
253
		try {
254
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
255
			$token = $this->request->getParam('token', null);
256
			$share = $this->ocmMiddleware->getValidShare($id, $token);
257
			$this->fedShareManager->acceptShare($share);
258
		} catch (NotImplementedException $e) {
259
			return new Result(
260
				null,
261
				Http::STATUS_SERVICE_UNAVAILABLE,
262
				'Server does not support federated cloud sharing'
263
			);
264
		}
265
		return new Result();
266
	}
267
268
	/**
269
	 * @NoCSRFRequired
270
	 * @PublicPage
271
	 *
272
	 * decline server-to-server share
273
	 *
274
	 * @param int $id
275
	 *
276
	 * @return Result
277
	 */
278 View Code Duplication
	public function declineShare($id) {
279
		try {
280
			$token = $this->request->getParam('token', null);
281
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
282
			$share = $this->ocmMiddleware->getValidShare($id, $token);
283
			$this->fedShareManager->declineShare($share);
284
		} catch (NotImplementedException $e) {
285
			return new Result(
286
				null,
287
				Http::STATUS_SERVICE_UNAVAILABLE,
288
				'Server does not support federated cloud sharing'
289
			);
290
		}
291
292
		return new Result();
293
	}
294
295
	/**
296
	 * @NoCSRFRequired
297
	 * @PublicPage
298
	 *
299
	 * remove server-to-server share if it was unshared by the owner
300
	 *
301
	 * @param int $id
302
	 *
303
	 * @return Result
304
	 */
305 View Code Duplication
	public function unshare($id) {
306
		try {
307
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
308
			$token = $this->request->getParam('token', null);
309
			if ($token && $id) {
310
				$this->fedShareManager->unshare($id, $token);
311
			}
312
		} catch (NotImplementedException $e) {
313
			return new Result(
314
				null,
315
				Http::STATUS_SERVICE_UNAVAILABLE,
316
				'Server does not support federated cloud sharing'
317
			);
318
		} catch (\Exception $e) {
319
			// pass
320
		}
321
		return new Result();
322
	}
323
324
	/**
325
	 * @NoCSRFRequired
326
	 * @PublicPage
327
	 *
328
	 * federated share was revoked, either by the owner or the re-sharer
329
	 *
330
	 * @param int $id
331
	 *
332
	 * @return Result
333
	 */
334 View Code Duplication
	public function revoke($id) {
335
		try {
336
			$token = $this->request->getParam('token', null);
337
			$share = $this->ocmMiddleware->getValidShare($id, $token);
338
			$this->fedShareManager->undoReshare($share);
339
		} catch (\Exception $e) {
340
			return new Result(null, Http::STATUS_BAD_REQUEST);
341
		}
342
343
		return new Result();
344
	}
345
346
	/**
347
	 * @NoCSRFRequired
348
	 * @PublicPage
349
	 *
350
	 * update share information to keep federated re-shares in sync
351
	 *
352
	 * @param int $id
353
	 *
354
	 * @return Result
355
	 */
356
	public function updatePermissions($id) {
357
		try {
358
			$permissions = $this->request->getParam('permissions', null);
359
			$token = $this->request->getParam('token', null);
360
			$share = $this->ocmMiddleware->getValidShare($id, $token);
361
			$validPermission = \ctype_digit((string)$permissions);
362
			if (!$validPermission) {
363
				throw new \Exception();
364
			}
365
			$permissions = $this->ocmMiddleware->normalizePermissions(
366
				(int) $permissions
367
			);
368
			$this->fedShareManager->updatePermissions($share, $permissions);
369
		} catch (\Exception $e) {
370
			return new Result(null, Http::STATUS_BAD_REQUEST);
371
		}
372
373
		return new Result();
374
	}
375
}
376