Completed
Pull Request — stable8.2 (#24656)
by Joas
12:22
created

Local::createShare()   F

Complexity

Conditions 29
Paths 1980

Size

Total Lines 107
Code Lines 73

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 61
CRAP Score 31.3474
Metric Value
dl 0
loc 107
ccs 61
cts 71
cp 0.8592
rs 2
cc 29
eloc 73
nc 1980
nop 1
crap 31.3474

How to fix   Long Method    Complexity   

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 Björn Schießle <[email protected]>
4
 * @author Joas Schilling <[email protected]>
5
 * @author Morris Jobke <[email protected]>
6
 * @author Robin Appelman <[email protected]>
7
 * @author Roeland Jago Douma <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 * @author Vincent Petry <[email protected]>
10
 *
11
 * @copyright Copyright (c) 2015, ownCloud, Inc.
12
 * @license AGPL-3.0
13
 *
14
 * This code is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License, version 3,
16
 * as published by the Free Software Foundation.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License, version 3,
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
25
 *
26
 */
27
28
namespace OCA\Files_Sharing\API;
29
30
use OC\HintException;
31
32
class Local {
33
34
	/**
35
	 * get all shares
36
	 *
37
	 * @param array $params option 'file' to limit the result to a specific file/folder
38
	 * @return \OC_OCS_Result share information
39
	 */
40 12
	public static function getAllShares($params) {
0 ignored issues
show
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
41 12
		if (isset($_GET['shared_with_me']) && $_GET['shared_with_me'] !== 'false') {
42 1
				return self::getFilesSharedWithMe();
43
			}
44
		// if a file is specified, get the share for this file
45 11
		if (isset($_GET['path'])) {
46 10
			if ( isset($_GET['reshares']) && $_GET['reshares'] !== 'false' ) {
47 1
				$reshares = true;
48 1
			} else {
49 10
				$reshares = false;
50
			}
51
52 10
			if (isset($_GET['subfiles']) && $_GET['subfiles'] !== 'false') {
53 6
				return self::getSharesFromFolder($_GET['path']);
54
			}
55 4
			return self::collectShares(self::getFileId($_GET['path']),
56 4
			                           self::getItemType($_GET['path']),
57 4
			                           false,
58 4
			                           $_GET['path'],
59 4
			                           $reshares);
60
		}
61
62 2
		$shares = \OCP\Share::getItemShared('file', null);
63
64 2
		if ($shares === false) {
65
			return new \OC_OCS_Result(null, 404, 'could not get shares');
66
		} else {
67 2
			foreach ($shares as &$share) {
68 2 View Code Duplication
				if ($share['item_type'] === 'file' && isset($share['path'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69 1
					$share['mimetype'] = \OC_Helper::getFileNameMimeType($share['path']);
70 1
					if (\OC::$server->getPreviewManager()->isMimeSupported($share['mimetype'])) {
71 1
						$share['isPreviewAvailable'] = true;
72 1
					}
73 1
				}
74
75 2 View Code Duplication
				if (!is_null($share['token'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
76 1
					$share['url'] = \OC::$server->getURLGenerator()->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share['token']]);
77 1
				}
78 2
			}
79 2
			return new \OC_OCS_Result($shares);
80
		}
81
82
	}
83
84
	/**
85
	 * get share information for a given share
86
	 *
87
	 * @param array $params which contains a 'id'
88
	 * @return \OC_OCS_Result share information
89
	 */
90 3
	public static function getShare($params) {
91
92 3
		$s = self::getShareFromId($params['id']);
93
94 3
		return self::collectShares($s['file_source'], $s['item_type'], true, null, false, (int)$params['id']);
95
	}
96
97
	/**
98
	 * collect all share information, either of a specific share or all
99
	 *        shares for a given path
100
	 *
101
	 * @param string $itemSource
102
	 * @param string $itemType
103
	 * @param bool $getSpecificShare
104
	 * @param string $path
105
	 * @param bool $reshares
106
	 * @param int $id
107
	 *
108
	 * @return \OC_OCS_Result
109
	 */
110 6
	private static function collectShares($itemSource, $itemType, $getSpecificShare = false, $path = null, $reshares = false, $id = null) {
111 6
		if ($itemSource !== null) {
112 5
			$shares = \OCP\Share::getItemShared($itemType, $itemSource);
113 5
			$receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $itemSource);
114
			// if a specific share was specified only return this one
115 5
			if ($getSpecificShare === true) {
116 2
				foreach ($shares as $share) {
117 2
					if ($share['id'] === $id) {
118 2
						$shares = array('element' => $share);
119 2
						break;
120
					}
121 2
				}
122 2
			} else {
123 4
				foreach ($shares as $key => $share) {
124 4
					$shares[$key]['path'] = $path;
125 4
				}
126
			}
127
128
129
			// include also reshares in the lists. This means that the result
130
			// will contain every user with access to the file.
131 5
			if ($reshares === true) {
132 1
				$shares = self::addReshares($shares, $itemSource);
133 1
			}
134
135 5
			if ($receivedFrom) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $receivedFrom of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
136 1
				foreach ($shares as $key => $share) {
137 1
					$shares[$key]['received_from'] = $receivedFrom['uid_owner'];
138 1
					$shares[$key]['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']);
139 1
				}
140 1
			}
141 5
		} else {
142 1
			$shares = null;
143
		}
144
145 6
		if ($shares === null || empty($shares)) {
146 1
			return new \OC_OCS_Result(null, 404, 'share doesn\'t exist');
147
		} else {
148 5
			foreach ($shares as &$share) {
149 5 View Code Duplication
				if (!is_null($share['token'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150 3
					$share['url'] = \OC::$server->getURLGenerator()->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share['token']]);
151 3
				}
152 5
			}
153
154 5
			return new \OC_OCS_Result($shares);
155
		}
156
	}
157
158
	/**
159
	 * add reshares to a array of shares
160
	 * @param array $shares array of shares
161
	 * @param int $itemSource item source ID
162
	 * @return array new shares array which includes reshares
163
	 */
164 1
	private static function addReshares($shares, $itemSource) {
165
166
		// if there are no shares than there are also no reshares
167 1
		$firstShare = reset($shares);
168 1
		if ($firstShare) {
169 1
			$path = $firstShare['path'];
170 1
		} else {
171
			return $shares;
172
		}
173
174 1
		$select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `file_source`, `path` , `*PREFIX*share`.`permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`, `mail_send`';
175 1
		$getReshares = \OCP\DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` WHERE `*PREFIX*share`.`file_source` = ? AND `*PREFIX*share`.`item_type` IN (\'file\', \'folder\') AND `uid_owner` != ?');
176 1
		$reshares = $getReshares->execute(array($itemSource, \OCP\User::getUser()))->fetchAll();
177
178 1
		foreach ($reshares as $key => $reshare) {
179 1
			if (isset($reshare['share_with']) && $reshare['share_with'] !== '') {
180 1
				$reshares[$key]['share_with_displayname'] = \OCP\User::getDisplayName($reshare['share_with']);
181 1
			}
182
			// add correct path to the result
183 1
			$reshares[$key]['path'] = $path;
184 1
		}
185
186 1
		return array_merge($shares, $reshares);
187
	}
188
189
	/**
190
	 * get share from all files in a given folder (non-recursive)
191
	 * @param string $path
192
	 * @return \OC_OCS_Result
193
	 */
194 6
	private static function getSharesFromFolder($path) {
195 6
		$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files');
196
197 6
		if(!$view->is_dir($path)) {
198 1
			return new \OC_OCS_Result(null, 400, "not a directory");
199
		}
200
201 5
		$content = $view->getDirectoryContent($path);
202
203 5
		$result = array();
204 5
		foreach ($content as $file) {
205
			// workaround because folders are named 'dir' in this context
206 5
			$itemType = $file['type'] === 'file' ? 'file' : 'folder';
207 5
			$share = \OCP\Share::getItemShared($itemType, $file['fileid']);
208 5
			if($share) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $share of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
209 5
				$receivedFrom =  \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']);
210 5
				reset($share);
211 5
				$key = key($share);
212 5
				if ($receivedFrom) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $receivedFrom of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
213 3
					$share[$key]['received_from'] = $receivedFrom['uid_owner'];
214 3
					$share[$key]['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']);
215 3
				}
216 5
				$result = array_merge($result, $share);
217 5
			}
218 5
		}
219
220 5
		return new \OC_OCS_Result($result);
221
	}
222
223
	/**
224
	 * get files shared with the user
225
	 * @return \OC_OCS_Result
226
	 */
227 1
	private static function getFilesSharedWithMe() {
228
		try	{
229 1
			$shares = \OCP\Share::getItemsSharedWith('file');
230 1
			foreach ($shares as &$share) {
231 1 View Code Duplication
				if ($share['item_type'] === 'file') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
232 1
					$share['mimetype'] = \OC_Helper::getFileNameMimeType($share['file_target']);
233 1
					if (\OC::$server->getPreviewManager()->isMimeSupported($share['mimetype'])) {
234 1
						$share['isPreviewAvailable'] = true;
235 1
					}
236 1
				}
237 1
			}
238 1
			$result = new \OC_OCS_Result($shares);
239 1
		} catch (\Exception $e) {
240
			$result = new \OC_OCS_Result(null, 403, $e->getMessage());
241
		}
242
243 1
		return $result;
244
245
	}
246
247
	/**
248
	 * create a new share
249
	 * @param array $params
250
	 * @return \OC_OCS_Result
251
	 */
252 18
	public static function createShare($params) {
0 ignored issues
show
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
253
254 18
		$path = isset($_POST['path']) ? $_POST['path'] : null;
255
256 18
		if($path === null) {
257
			return new \OC_OCS_Result(null, 400, "please specify a file or folder path");
258
		}
259 18
		$itemSource = self::getFileId($path);
260 18
		$itemSourceName = $itemSource;
261 18
		$itemType = self::getItemType($path);
262 18
		$expirationDate = null;
263
264 18
		if($itemSource === null) {
265
			return new \OC_OCS_Result(null, 404, "wrong path, file/folder doesn't exist.");
266
		}
267
268 18
		$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
269 18
		$shareType = isset($_POST['shareType']) ? (int)$_POST['shareType'] : null;
270
271
		switch($shareType) {
272 18
			case \OCP\Share::SHARE_TYPE_REMOTE:
273
				$shareWith = rtrim($shareWith, '/');
274
				$itemSourceName = basename($path);
275 18
			case \OCP\Share::SHARE_TYPE_USER:
276 18
			case \OCP\Share::SHARE_TYPE_GROUP:
277 6
				$permissions = isset($_POST['permissions']) ? (int)$_POST['permissions'] : 31;
278 6
				break;
279 12
			case \OCP\Share::SHARE_TYPE_LINK:
280
				//allow password protection
281 12
				$shareWith = isset($_POST['password']) ? $_POST['password'] : null;
282
				//check public link share
283 12
				$publicUploadEnabled = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_public_upload', 'yes');
284 12
				if(isset($_POST['publicUpload']) && $publicUploadEnabled !== 'yes') {
285
					return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator");
286
				}
287 12
				$publicUpload = isset($_POST['publicUpload']) ? $_POST['publicUpload'] : 'false';
288
				// read, create, update (7) if public upload is enabled or
289
				// read (1) if public upload is disabled
290 12
				$permissions = $publicUpload === 'true' ? 7 : 1;
291
292
				// Get the expiration date
293
				try {
294 12
					$expirationDate = isset($_POST['expireDate']) ? self::parseDate($_POST['expireDate']) : null;
295 12
				} catch (\Exception $e) {
296 4
					return new \OC_OCS_Result(null, 404, 'Invalid Date. Format must be YYYY-MM-DD.');
297
				}
298
299 8
				break;
300
			default:
301
				return new \OC_OCS_Result(null, 400, "unknown share type");
302
		}
303
304 14
		if (($permissions & \OCP\Constants::PERMISSION_READ) === 0) {
305 1
			return new \OC_OCS_Result(null, 400, 'invalid permissions');
306
		}
307
308
		try	{
309 13
			$token = \OCP\Share::shareItem(
310 13
					$itemType,
311 13
					$itemSource,
312 13
					$shareType,
313 13
					$shareWith,
314 13
					$permissions,
315 13
					$itemSourceName,
316
					$expirationDate
317 13
			);
318 13
		} catch (HintException $e) {
319 2
			if ($e->getCode() === 0) {
320
				return new \OC_OCS_Result(null, 400, $e->getHint());
321
			} else {
322 2
				return new \OC_OCS_Result(null, $e->getCode(), $e->getHint());
323
			}
324 2
		} catch (\Exception $e) {
325 2
			return new \OC_OCS_Result(null, 403, $e->getMessage());
326
		}
327
328 11
		if ($token) {
329 11
			$data = array();
330 11
			$data['id'] = 'unknown';
331 11
			$shares = \OCP\Share::getItemShared($itemType, $itemSource);
332 11
			if(is_string($token)) { //public link share
333 6
				foreach ($shares as $share) {
334 6
					if ($share['token'] === $token) {
335 6
						$data['id'] = $share['id'];
336 6
						break;
337
					}
338 6
				}
339 6
				$data['url'] = \OC::$server->getURLGenerator()->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
340 6
				$data['token'] = $token;
341
342 6
			} else {
343 5
				foreach ($shares as $share) {
344 5
					if ($share['share_with'] === $shareWith && $share['share_type'] === $shareType) {
345 5
						$data['id'] = $share['id'];
346 5
						break;
347
					}
348 5
				}
349
			}
350
351 11
			$data['permissions'] = $share['permissions'];
0 ignored issues
show
Bug introduced by
The variable $share 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...
352 11
			$data['expiration'] = $share['expiration'];
353
354 11
			return new \OC_OCS_Result($data);
355
		} else {
356
			return new \OC_OCS_Result(null, 404, "couldn't share file");
357
		}
358
	}
359
360
	/**
361
	 * update shares, e.g. password, permissions, etc
362
	 * @param array $params shareId 'id' and the parameter we want to update
363
	 *                      currently supported: permissions, password, publicUpload
364
	 * @return \OC_OCS_Result
365
	 */
366 5
	public static function updateShare($params) {
367
368 5
		$share = self::getShareFromId($params['id']);
369
370 5
		if(!isset($share['file_source'])) {
371
			return new \OC_OCS_Result(null, 404, "wrong share Id, share doesn't exist.");
372
		}
373
374
		try {
375 5
			if(isset($params['_put']['permissions'])) {
376 2
				return self::updatePermissions($share, $params);
377 4
			} elseif (isset($params['_put']['password'])) {
378 2
				return self::updatePassword($params['id'], (int)$share['share_type'], $params['_put']['password']);
379 2
			} elseif (isset($params['_put']['publicUpload'])) {
380 1
				return self::updatePublicUpload($share, $params);
381 1
			} elseif (isset($params['_put']['expireDate'])) {
382 1
				return self::updateExpireDate($share, $params);
383
			}
384
		} catch (\Exception $e) {
385
386
			return new \OC_OCS_Result(null, 400, $e->getMessage());
387
		}
388
389
		return new \OC_OCS_Result(null, 400, "Wrong or no update parameter given");
390
	}
391
392
	/**
393
	 * update permissions for a share
394
	 * @param array $share information about the share
395
	 * @param array $params contains 'permissions'
396
	 * @return \OC_OCS_Result
397
	 */
398 3
	private static function updatePermissions($share, $params) {
399
400 3
		$itemSource = $share['item_source'];
401 3
		$itemType = $share['item_type'];
402 3
		$shareWith = $share['share_with'];
403 3
		$shareType = $share['share_type'];
404 3
		$permissions = isset($params['_put']['permissions']) ? (int)$params['_put']['permissions'] : null;
405
406 3
		$publicUploadStatus = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_public_upload', 'yes');
407 3
		$publicUploadEnabled = ($publicUploadStatus === 'yes') ? true : false;
408
409
410
		// only change permissions for public shares if public upload is enabled
411
		// and we want to set permissions to 1 (read only) or 7 (allow upload)
412 3
		if ( (int)$shareType === \OCP\Share::SHARE_TYPE_LINK ) {
413 1
			if ($publicUploadEnabled === false || ($permissions !== 7 && $permissions !== 1)) {
414
				return new \OC_OCS_Result(null, 400, "can't change permission for public link share");
415
			}
416 1
		}
417
418 3
		if (($permissions & \OCP\Constants::PERMISSION_READ) === 0) {
419 1
			return new \OC_OCS_Result(null, 400, 'invalid permissions');
420
		}
421
422
		try {
423 2
			$return = \OCP\Share::setPermissions(
424 2
					$itemType,
425 2
					$itemSource,
426 2
					$shareType,
427 2
					$shareWith,
428
					$permissions
429 2
					);
430 2
		} catch (\Exception $e) {
431
			return new \OC_OCS_Result(null, 404, $e->getMessage());
432
		}
433
434 2
		if ($return) {
435 2
			return new \OC_OCS_Result();
436
		} else {
437
			return new \OC_OCS_Result(null, 404, "couldn't set permissions");
438
		}
439
	}
440
441
	/**
442
	 * enable/disable public upload
443
	 * @param array $share information about the share
444
	 * @param array $params contains 'publicUpload' which can be 'yes' or 'no'
445
	 * @return \OC_OCS_Result
446
	 */
447 1
	private static function updatePublicUpload($share, $params) {
448
449 1
		$publicUploadEnabled = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_public_upload', 'yes');
450 1
		if($publicUploadEnabled !== 'yes') {
451
			return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator");
452
		}
453
454 1
		if ($share['item_type'] !== 'folder' ||
455 1
				(int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) {
456
			return new \OC_OCS_Result(null, 400, "public upload is only possible for public shared folders");
457
		}
458
459
		// read, create, update (7) if public upload is enabled or
460
		// read (1) if public upload is disabled
461 1
		$params['_put']['permissions'] = $params['_put']['publicUpload'] === 'true' ? 7 : 1;
462
463 1
		return self::updatePermissions($share, $params);
464
465
	}
466
467
	/**
468
	 * set expire date for public link share
469
	 * @param array $share information about the share
470
	 * @param array $params contains 'expireDate' which needs to be a well formated date string, e.g DD-MM-YYYY
471
	 * @return \OC_OCS_Result
472
	 */
473 1
	private static function updateExpireDate($share, $params) {
474
		// only public links can have a expire date
475 1
		if ((int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) {
476
			return new \OC_OCS_Result(null, 400, "expire date only exists for public link shares");
477
		}
478
479
		try {
480 1
			$expireDateSet = \OCP\Share::setExpirationDate($share['item_type'], $share['item_source'], $params['_put']['expireDate'], (int)$share['stime']);
481 1
			$result = ($expireDateSet) ? new \OC_OCS_Result() : new \OC_OCS_Result(null, 404, "couldn't set expire date");
482 1
		} catch (\Exception $e) {
483 1
			$result = new \OC_OCS_Result(null, 404, $e->getMessage());
484
		}
485
486 1
		return $result;
487
488
	}
489
490
	/**
491
	 * update password for public link share
492
	 * @param int $shareId
493
	 * @param int $shareType 
494
	 * @param string $password
495
	 * @return \OC_OCS_Result
496
	 */
497 2
	private static function updatePassword($shareId, $shareType, $password) {
498 2
		if($shareType !== \OCP\Share::SHARE_TYPE_LINK) {
499
			return  new \OC_OCS_Result(null, 400, "password protection is only supported for public shares");
500
		}
501
502 2
		if($password === '') {
503 2
			$password = null;
504 2
		}
505
506
		try {
507 2
			$result = \OCP\Share::setPassword($shareId, $password);
508 2
		} catch (\Exception $e) {
509 1
			return new \OC_OCS_Result(null, 403, $e->getMessage());
510
		}
511
512 2
		if($result) {
513 2
			return new \OC_OCS_Result();
514
		}
515
516
		return new \OC_OCS_Result(null, 404, "couldn't set password");
517
	}
518
519
	/**
520
	 * unshare a file/folder
521
	 * @param array $params contains the shareID 'id' which should be unshared
522
	 * @return \OC_OCS_Result
523
	 */
524 2
	public static function deleteShare($params) {
525
526 2
		$share = self::getShareFromId($params['id']);
527 2
		$fileSource = isset($share['file_source']) ? $share['file_source'] : null;
528 2
		$itemType = isset($share['item_type']) ? $share['item_type'] : null;;
529
530 2
		if($fileSource === null) {
531
			return new \OC_OCS_Result(null, 404, "wrong share ID, share doesn't exist.");
532
		}
533
534 2
		$shareWith = isset($share['share_with']) ? $share['share_with'] : null;
535 2
		$shareType = isset($share['share_type']) ? (int)$share['share_type'] : null;
536
537 2
		if( $shareType === \OCP\Share::SHARE_TYPE_LINK) {
538 2
			$shareWith = null;
539 2
		}
540
541
		try {
542 2
			$return = \OCP\Share::unshare(
543 2
					$itemType,
544 2
					$fileSource,
545 2
					$shareType,
546 2
					$shareWith);
547 2
		} catch (\Exception $e) {
548
			return new \OC_OCS_Result(null, 404, $e->getMessage());
549
		}
550
551 2
		if ($return) {
552 2
			return new \OC_OCS_Result();
553
		} else {
554
			$msg = "Unshare Failed";
555
			return new \OC_OCS_Result(null, 404, $msg);
556
		}
557
	}
558
559
	/**
560
	 * Make sure that the passed date is valid ISO 8601
561
	 * So YYYY-MM-DD
562
	 * If not throw an exception
563
	 *
564
	 * @param string $expireDate
565
	 *
566
	 * @throws \Exception
567
	 * @return \DateTime
568
	 */
569 8
	private static function parseDate($expireDate) {
570 8
		if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $expireDate) === 0) {
571 4
			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
572
		}
573
574 4
		$date = new \DateTime($expireDate);
575
576 4
		if ($date === false) {
577
			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
578
		}
579
580 4
		return $date;
581
	}
582
583
	/**
584
	 * get file ID from a given path
585
	 * @param string $path
586
	 * @return string fileID or null
587
	 */
588 21 View Code Duplication
	private static function getFileId($path) {
589
590 21
		$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files');
591 21
		$fileId = null;
592 21
		$fileInfo = $view->getFileInfo($path);
593 21
		if ($fileInfo) {
594 21
			$fileId = $fileInfo['fileid'];
595 21
		}
596
597 21
		return $fileId;
598
	}
599
600
	/**
601
	 * get itemType
602
	 * @param string $path
603
	 * @return string type 'file', 'folder' or null of file/folder doesn't exists
604
	 */
605 21 View Code Duplication
	private static function getItemType($path) {
606 21
		$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files');
607 21
		$itemType = null;
608
609 21
		if ($view->is_dir($path)) {
610 15
			$itemType = "folder";
611 21
		} elseif ($view->is_file($path)) {
612 6
			$itemType = "file";
613 6
		}
614
615 21
		return $itemType;
616
	}
617
618
	/**
619
	 * get some information from a given share
620
	 * @param int $shareID
621
	 * @return array with: item_source, share_type, share_with, item_type, permissions
622
	 */
623 10
	private static function getShareFromId($shareID) {
624 10
		$sql = 'SELECT `file_source`, `item_source`, `share_type`, `share_with`, `item_type`, `permissions`, `stime` FROM `*PREFIX*share` WHERE `id` = ?';
625 10
		$args = array($shareID);
626 10
		$query = \OCP\DB::prepare($sql);
627 10
		$result = $query->execute($args);
628
629 10
		if (\OCP\DB::isError($result)) {
630
			\OCP\Util::writeLog('files_sharing', \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
631
			return null;
632
		}
633 10
		if ($share = $result->fetchRow()) {
634 9
			return $share;
635
		}
636
637 1
		return null;
638
639
	}
640
641
}
642