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

RequestHandlerController::declineShare()   A

Complexity

Conditions 2
Paths 5

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
nc 5
nop 1
dl 16
loc 16
rs 9.7333
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
			if ($ownerFederatedId === null) {
140
				$ownerFederatedId = $owner . '@' . $this->addressHandler->normalizeRemote($remote);
141
			}
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 = $ownerFederatedId;
146
			}
147
148
			$ownerAddress = new Address($ownerFederatedId);
149
			$sharedByAddress = new Address($sharedByFederatedId);
150
151
			$this->fedShareManager->createShare(
152
				$ownerAddress,
153
				$sharedByAddress,
154
				$shareWith,
155
				$remoteId,
156
				$name,
157
				$token
158
			);
159
		} catch (OcmException $e) {
160
			return new Result(
161
				null,
162
				$e->getHttpStatusCode(),
163
				$e->getMessage()
164
			);
165
		} catch (\Exception $e) {
166
			\OCP\Util::writeLog(
167
				'files_sharing',
168
				'server can not add remote share, ' . $e->getMessage(),
169
				\OCP\Util::ERROR
170
			);
171
			return new Result(
172
				null,
173
				Http::STATUS_INTERNAL_SERVER_ERROR,
174
				'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...
175
			);
176
		}
177
		return new Result();
178
	}
179
180
	/**
181
	 * @NoCSRFRequired
182
	 * @PublicPage
183
	 *
184
	 * create re-share on behalf of another user
185
	 *
186
	 * @param int $id
187
	 *
188
	 * @return Result
189
	 */
190
	public function reShare($id) {
191
		$token = $this->request->getParam('token', null);
192
		$shareWith = $this->request->getParam('shareWith', null);
193
		$permission = $this->request->getParam('permission', null);
194
		$remoteId = $this->request->getParam('remoteId', null);
195
196
		try {
197
			$this->ocmMiddleware->assertNotNull(
198
				[
199
					'id' => $id,
200
					'token' => $token,
201
					'shareWith' => $shareWith,
202
					'permission'  => $permission,
203
					'remoteId' => $remoteId
204
				]
205
			);
206
			$permission = (int) $permission;
207
			$remoteId = (int) $remoteId;
208
			$share = $this->ocmMiddleware->getValidShare($id, $token);
209
210
			// don't allow to share a file back to the owner
211
			$owner = $share->getShareOwner();
212
			$ownerAddress = $this->addressHandler->getLocalUserFederatedAddress($owner);
213
			$shareWithAddress = new Address($shareWith);
214
			$this->ocmMiddleware->assertNotSameUser($ownerAddress, $shareWithAddress);
215
216
			$this->ocmMiddleware->assertSharingPermissionSet($share);
217
			$result = $this->fedShareManager->reShare(
218
				$share,
219
				$remoteId,
220
				$shareWith,
221
				$permission
222
			);
223
		} catch (OcmException $e) {
224
			return new Result(
225
				null,
226
				$e->getHttpStatusCode(),
227
				$e->getMessage()
228
			);
229
		} catch (\Exception $e) {
230
			return new Result(null, Http::STATUS_BAD_REQUEST);
231
		}
232
233
		return new Result(
234
			[
235
				'token' => $result->getToken(),
236
				'remoteId' => $result->getId()
237
			]
238
		);
239
	}
240
241
	/**
242
	 * @NoCSRFRequired
243
	 * @PublicPage
244
	 *
245
	 * accept server-to-server share
246
	 *
247
	 * @param int $id
248
	 *
249
	 * @return Result
250
	 */
251 View Code Duplication
	public function acceptShare($id) {
252
		try {
253
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
254
			$token = $this->request->getParam('token', null);
255
			$share = $this->ocmMiddleware->getValidShare($id, $token);
256
			$this->fedShareManager->acceptShare($share);
257
		} catch (NotImplementedException $e) {
258
			return new Result(
259
				null,
260
				Http::STATUS_SERVICE_UNAVAILABLE,
261
				'Server does not support federated cloud sharing'
262
			);
263
		}
264
		return new Result();
265
	}
266
267
	/**
268
	 * @NoCSRFRequired
269
	 * @PublicPage
270
	 *
271
	 * decline server-to-server share
272
	 *
273
	 * @param int $id
274
	 *
275
	 * @return Result
276
	 */
277 View Code Duplication
	public function declineShare($id) {
278
		try {
279
			$token = $this->request->getParam('token', null);
280
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
281
			$share = $this->ocmMiddleware->getValidShare($id, $token);
282
			$this->fedShareManager->declineShare($share);
283
		} catch (NotImplementedException $e) {
284
			return new Result(
285
				null,
286
				Http::STATUS_SERVICE_UNAVAILABLE,
287
				'Server does not support federated cloud sharing'
288
			);
289
		}
290
291
		return new Result();
292
	}
293
294
	/**
295
	 * @NoCSRFRequired
296
	 * @PublicPage
297
	 *
298
	 * remove server-to-server share if it was unshared by the owner
299
	 *
300
	 * @param int $id
301
	 *
302
	 * @return Result
303
	 */
304 View Code Duplication
	public function unshare($id) {
305
		try {
306
			$this->ocmMiddleware->assertOutgoingSharingEnabled();
307
			$token = $this->request->getParam('token', null);
308
			if ($token && $id) {
309
				$this->fedShareManager->unshare($id, $token);
310
			}
311
		} catch (NotImplementedException $e) {
312
			return new Result(
313
				null,
314
				Http::STATUS_SERVICE_UNAVAILABLE,
315
				'Server does not support federated cloud sharing'
316
			);
317
		} catch (\Exception $e) {
318
			// pass
319
		}
320
		return new Result();
321
	}
322
323
	/**
324
	 * @NoCSRFRequired
325
	 * @PublicPage
326
	 *
327
	 * federated share was revoked, either by the owner or the re-sharer
328
	 *
329
	 * @param int $id
330
	 *
331
	 * @return Result
332
	 */
333 View Code Duplication
	public function revoke($id) {
334
		try {
335
			$token = $this->request->getParam('token', null);
336
			$share = $this->getValidShare($id, $token);
337
			$this->fedShareManager->revoke($share);
338
		} catch (\Exception $e) {
339
			return new Result(null, Http::STATUS_BAD_REQUEST);
340
		}
341
342
		return new Result();
343
	}
344
345
	/**
346
	 * @NoCSRFRequired
347
	 * @PublicPage
348
	 *
349
	 * update share information to keep federated re-shares in sync
350
	 *
351
	 * @param int $id
352
	 *
353
	 * @return Result
354
	 */
355
	public function updatePermissions($id) {
356
		try {
357
			$permissions = $this->request->getParam('permissions', null);
358
			$token = $this->request->getParam('token', null);
359
			$share = $this->ocmMiddleware->getValidShare($id, $token);
360
			$validPermission = \ctype_digit((string)$permissions);
361
			if (!$validPermission) {
362
				throw new \Exception();
363
			}
364
			$this->fedShareManager->updatePermissions($share, (int)$permissions);
365
		} catch (\Exception $e) {
366
			return new Result(null, Http::STATUS_BAD_REQUEST);
367
		}
368
369
		return new Result();
370
	}
371
}
372