Completed
Push — master ( 5412c2...2d62f9 )
by Blizzz
45:23 queued 29:26
created

ShareesAPIController::isV2()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Björn Schießle <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Roeland Jago Douma <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 * @author Arthur Schiwon <[email protected]>
10
 *
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
namespace OCA\Files_Sharing\Controller;
27
28
use OCP\AppFramework\Http\DataResponse;
29
use OCP\AppFramework\OCS\OCSBadRequestException;
30
use OCP\AppFramework\OCSController;
31
use OCP\Collaboration\Collaborators\ISearch;
32
use OCP\IRequest;
33
use OCP\IConfig;
34
use OCP\IURLGenerator;
35
use OCP\Share;
36
use OCP\Share\IManager;
37
38
class ShareesAPIController extends OCSController {
39
	/** @var IConfig */
40
	protected $config;
41
42
	/** @var IURLGenerator */
43
	protected $urlGenerator;
44
45
	/** @var IManager */
46
	protected $shareManager;
47
48
	/** @var bool */
49
	protected $shareWithGroupOnly = false;
50
51
	/** @var bool */
52
	protected $shareeEnumeration = true;
53
54
	/** @var int */
55
	protected $offset = 0;
56
57
	/** @var int */
58
	protected $limit = 10;
59
60
	/** @var array */
61
	protected $result = [
62
		'exact' => [
63
			'users' => [],
64
			'groups' => [],
65
			'remotes' => [],
66
			'emails' => [],
67
			'circles' => [],
68
		],
69
		'users' => [],
70
		'groups' => [],
71
		'remotes' => [],
72
		'emails' => [],
73
		'lookup' => [],
74
		'circles' => [],
75
	];
76
77
	protected $reachedEndFor = [];
78
	/** @var ISearch */
79
	private $collaboratorSearch;
80
81
	/**
82
	 * @param string $appName
83
	 * @param IRequest $request
84
	 * @param IConfig $config
85
	 * @param IURLGenerator $urlGenerator
86
	 * @param IManager $shareManager
87
	 * @param ISearch $collaboratorSearch
88
	 */
89
	public function __construct(
90
		$appName,
91
		IRequest $request,
92
		IConfig $config,
93
		IURLGenerator $urlGenerator,
94
		IManager $shareManager,
95
		ISearch $collaboratorSearch
96
	) {
97
		parent::__construct($appName, $request);
98
99
		$this->config = $config;
100
		$this->urlGenerator = $urlGenerator;
101
		$this->shareManager = $shareManager;
102
		$this->collaboratorSearch = $collaboratorSearch;
103
	}
104
105
	/**
106
	 * @NoAdminRequired
107
	 *
108
	 * @param string $search
109
	 * @param string $itemType
110
	 * @param int $page
111
	 * @param int $perPage
112
	 * @param int|int[] $shareType
113
	 * @param bool $lookup
114
	 * @return DataResponse
115
	 * @throws OCSBadRequestException
116
	 */
117
	public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
0 ignored issues
show
Coding Style introduced by
search uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
118
119
		// only search for string larger than a given threshold
120
		$threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
121
		if (strlen($search) < $threshold) {
122
			return new DataResponse($this->result);
123
		}
124
125
		// never return more than the max. number of results configured in the config.php
126
		$maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
127
		if ($maxResults > 0) {
128
			$perPage = min($perPage, $maxResults);
129
		}
130
		if ($perPage <= 0) {
131
			throw new OCSBadRequestException('Invalid perPage argument');
132
		}
133
		if ($page <= 0) {
134
			throw new OCSBadRequestException('Invalid page');
135
		}
136
137
		$shareTypes = [
138
			Share::SHARE_TYPE_USER,
139
		];
140
141
		if ($itemType === null) {
142
			throw new OCSBadRequestException('Missing itemType');
143
		} elseif ($itemType === 'file' || $itemType === 'folder') {
144
			if ($this->shareManager->allowGroupSharing()) {
145
				$shareTypes[] = Share::SHARE_TYPE_GROUP;
146
			}
147
148
			if ($this->isRemoteSharingAllowed($itemType)) {
149
				$shareTypes[] = Share::SHARE_TYPE_REMOTE;
150
			}
151
152
			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
153
				$shareTypes[] = Share::SHARE_TYPE_EMAIL;
154
			}
155
		} else {
156
			$shareTypes[] = Share::SHARE_TYPE_GROUP;
157
			$shareTypes[] = Share::SHARE_TYPE_EMAIL;
158
		}
159
160
		// FIXME: DI
161
		if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
162
			$shareTypes[] = Share::SHARE_TYPE_CIRCLE;
163
		}
164
165
		if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
166
			$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
167
			sort($shareTypes);
168
		} else if (is_numeric($shareType)) {
169
			$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
170
			sort($shareTypes);
171
		}
172
173
		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
174
		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
175
		$this->limit = (int) $perPage;
176
		$this->offset = $perPage * ($page - 1);
177
178
		list($result, $hasMoreResults) = $this->collaboratorSearch->search($search, $shareTypes, $lookup, $this->limit, $this->offset);
179
180
		// extra treatment for 'exact' subarray, with a single merge expected keys might be lost
181
		if(isset($result['exact'])) {
182
			$result['exact'] = array_merge($this->result['exact'], $result['exact']);
183
		}
184
		$this->result = array_merge($this->result, $result);
185
		$response = new DataResponse($this->result);
186
187
		if ($hasMoreResults) {
188
			$response->addHeader('Link', $this->getPaginationLink($page, [
189
				'search' => $search,
190
				'itemType' => $itemType,
191
				'shareType' => $shareTypes,
192
				'perPage' => $perPage,
193
			]));
194
		}
195
196
		return $response;
197
	}
198
199
	/**
200
	 * Method to get out the static call for better testing
201
	 *
202
	 * @param string $itemType
203
	 * @return bool
204
	 */
205
	protected function isRemoteSharingAllowed($itemType) {
206
		try {
207
			// FIXME: static foo makes unit testing unnecessarily difficult
208
			$backend = \OC\Share\Share::getBackend($itemType);
209
			return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
210
		} catch (\Exception $e) {
211
			return false;
212
		}
213
	}
214
215
216
	/**
217
	 * Generates a bunch of pagination links for the current page
218
	 *
219
	 * @param int $page Current page
220
	 * @param array $params Parameters for the URL
221
	 * @return string
222
	 */
223
	protected function getPaginationLink($page, array $params) {
224
		if ($this->isV2()) {
225
			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
226
		} else {
227
			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
228
		}
229
		$params['page'] = $page + 1;
230
		$link = '<' . $url . http_build_query($params) . '>; rel="next"';
231
232
		return $link;
233
	}
234
235
	/**
236
	 * @return bool
237
	 */
238
	protected function isV2() {
239
		return $this->request->getScriptName() === '/ocs/v2.php';
240
	}
241
}
242