Completed
Pull Request — master (#1038)
by René
04:22
created

SystemService::getSiteUsersAndGroups()   B

Complexity

Conditions 8
Paths 40

Size

Total Lines 48
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 25
c 1
b 0
f 1
dl 0
loc 48
ccs 0
cts 42
cp 0
rs 8.4444
cc 8
nc 40
nop 8
crap 72

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU Affero General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU Affero General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Polls\Service;
25
26
use Exception;
27
use OCA\Polls\Exceptions\NotAuthorizedException;
28
use OCA\Polls\Exceptions\TooShortException;
29
use OCA\Polls\Exceptions\UsernameInvalidException;
30
31
use OCP\IGroupManager;
32
use OCP\IUser;
33
use OCP\IUserManager;
34
use OCP\IRequest;
35
use OCA\Polls\Db\Share;
36
use OCA\Polls\Db\ShareMapper;
37
use OCA\Polls\Db\Vote;
38
use OCA\Polls\Db\VoteMapper;
39
40
class SystemService {
41
42
	/** @var IGroupManager */
43
	private $groupManager;
44
45
	/** @var IUserManager */
46
	private $userManager;
47
48
	/** @var VoteMapper */
49
	private $voteMapper;
50
51
	/** @var ShareMapper */
52
	private $shareMapper;
53
54
	/**
55
	 * SystemService constructor.
56
	 * @param IGroupManager $groupManager
57
	 * @param IUserManager $userManager
58
	 * @param VoteMapper $voteMapper
59
	 * @param ShareMapper $shareMapper
60
	 */
61
	public function __construct(
62
		IGroupManager $groupManager,
63
		IUserManager $userManager,
64
		VoteMapper $voteMapper,
65
		ShareMapper $shareMapper
66
	) {
67
		$this->groupManager = $groupManager;
68
		$this->userManager = $userManager;
69
		$this->voteMapper = $voteMapper;
70
		$this->shareMapper = $shareMapper;
71
	}
72
73
	/**
74
	 * Validate string as email address
75
	 * @NoAdminRequired
76
	 * @param string $query
77
	 * @return bool
78
	 */
79
	 private function isValidEmail($email) {
80
		 return (!preg_match('/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/', $email)) ? false : true;
81
	 }
82
83
84
	 /**
85
 	 * Get a list of users
86
 	 * @NoAdminRequired
87
 	 * @param string $query
88
 	 * @param array $skip - usernames to skip in return array
89
 	 * @return Array
90
 	 */
91
	 public function getSiteUsers($query = '', $skip = array()) {
92
		 $users = array();
93
		 foreach ($this->userManager->searchDisplayName($query) as $user) {
94
			 if (!in_array($user->getUID(), $skip) && $user->isEnabled()) {
95
				 $users[] = [
96
					 'id' => $user->getUID(),
97
					 'user' => $user->getUID(),
98
					 'displayName' => $user->getDisplayName(),
99
					 'organisation' => '',
100
					 'emailAddress' => $user->getEMailAddress(),
101
					 'desc' => 'User',
102
					 'type' => 'user',
103
					 'icon' => 'icon-user',
104
					 'avatarURL' => '',
105
					 'avatar' => '',
106
					 'lastLogin' => $user->getLastLogin(),
107
					 'cloudId' => $user->getCloudId()
108
				 ];
109
			 }
110
		 }
111
		 return $users;
112
	 }
113
114
	 /**
115
 	 * Get a list of user groups
116
 	 * @NoAdminRequired
117
 	 * @param string $query
118
 	 * @param array $skip - group names to skip in return array
119
 	 * @return Array
120
 	 */
121
	 public function getSiteGroups($query = '', $skip = array()) {
122
		$groups = array();
123
		foreach ($this->groupManager->search($query) as $group) {
124
			if (!in_array($group->getGID(), $skip)) {
125
				$groups[] = [
126
					'id' => $group->getGID(),
127
					'user' => $group->getGID(),
128
					'organisation' => '',
129
					'displayName' => $group->getDisplayName(),
130
					'emailAddress' => '',
131
					'desc' => 'Group',
132
					'type' => 'group',
133
					'icon' => 'icon-group',
134
					'avatarURL' => '',
135
					'avatar' => '',
136
					'lastLogin' => '',
137
					'cloudId' => ''
138
139
				];
140
			}
141
		}
142
		return $groups;
143
	}
144
145
	/**
146
	 * Get a list of contacts
147
	 * @NoAdminRequired
148
	 * @param string $query
149
	 * @return Array
150
	 */
151
	public function getContacts($query = '') {
152
		$contacts = array();
153
		foreach (\OC::$server->getContactsManager()->search($query, array('FN', 'EMAIL', 'ORG', 'CATEGORIES')) as $contact) {
154
			if (!array_key_exists('isLocalSystemBook', $contact) && array_key_exists('EMAIL', $contact)) {
155
156
				$emailAdresses = $contact['EMAIL'];
157
158
				if (!is_array($emailAdresses)) {
159
					$emailAdresses = array($emailAdresses);
160
				} else {
161
					// take the first eMail address for now
162
					$emailAdresses = array($emailAdresses[0]);
163
				}
164
165
				foreach ($emailAdresses as $emailAddress) {
166
					$contacts[] = [
167
						'id' => $contact['UID'],
168
						'user' => $contact['FN'],
169
						'displayName' => $contact['FN'],
170
						'organisation' => isset($contact['ORG']) ? $contact['ORG'] : '',
171
						'emailAddress' => $emailAddress,
172
						'desc' => 'Contact',
173
						'type' => 'contact',
174
						'icon' => 'icon-mail',
175
						'avatarURL' => '',
176
						'avatar' => '',
177
						'lastLogin' => '',
178
						'cloudId' => '',
179
					];
180
				}
181
182
			}
183
		}
184
		return $contacts;
185
	}
186
187
	/**
188
	 * Get a list of contacts
189
	 * @NoAdminRequired
190
	 * @param string $query
191
	 * @return Array
192
	 */
193
	public function getContactsGroupMembers($query = '') {
194
		$contacts = array();
195
		\OC::$server->getLogger()->alert('Suche nach Gruppe: ' . $query);
196
		foreach (\OC::$server->getContactsManager()->search($query, array('CATEGORIES')) as $contact) {
197
			if (
198
				   !array_key_exists('isLocalSystemBook', $contact)
199
				&& array_key_exists('EMAIL', $contact)
200
				&& in_array($query, explode(',', $contact['CATEGORIES']))
201
			) {
202
				$emailAdresses = $contact['EMAIL'];
203
204
				if (!is_array($emailAdresses)) {
205
					$emailAdresses = array($emailAdresses);
206
				} else {
207
					// take the first eMail address for now
208
					$emailAdresses = array($emailAdresses[0]);
209
				}
210
211
				foreach ($emailAdresses as $emailAddress) {
212
					$contacts[] = [
213
						'id' => $contact['UID'],
214
						'user' => $contact['FN'],
215
						'displayName' => $contact['FN'],
216
						'organisation' => isset($contact['ORG']) ? $contact['ORG'] : '',
217
						'emailAddress' => $emailAddress,
218
						'desc' => 'Contact',
219
						'type' => 'contact',
220
						'icon' => 'icon-mail',
221
						'avatarURL' => '',
222
						'avatar' => '',
223
						'lastLogin' => '',
224
						'cloudId' => '',
225
					];
226
				}
227
			}
228
		}
229
		return $contacts;
230
	}
231
232
	/**
233
	 * Get a list of contact groups
234
	 * @NoAdminRequired
235
	 * @param string $query
236
	 * @return Array
237
	 */
238
	public function getContactsGroups($query = '') {
239
		$contactGroups = array();
240
		$foundContacts = [];
241
242
		foreach (\OC::$server->getContactsManager()->search($query, array('CATEGORIES')) as $contact) {
243
244
			foreach (explode(',', $contact['CATEGORIES']) as $contactGroup) {
245
				if (strpos($contactGroup, $query) === 0 && !in_array($contactGroup, $foundContacts)) {
246
					$foundContacts[] = $contactGroup;
247
					$contactGroups[] = [
248
						'id' => 'contactgroup_' + $contactGroup,
249
						'user' => $contactGroup,
250
						'displayName' => $contactGroup,
251
						'organisation' => '',
252
						'emailAddress' => '',
253
						'desc' => 'Contact Group',
254
						'type' => 'contactGroup',
255
						'icon' => 'icon-group',
256
						'avatarURL' => '',
257
						'avatar' => '',
258
						'lastLogin' => '',
259
						'cloudId' => '',
260
					];
261
				};
262
			}
263
		}
264
		return $contactGroups;
265
	}
266
267
268
	/**
269
	 * Get a combined list of NC users, groups and contacts
270
	 * @NoAdminRequired
271
	 * @param string $query
272
	 * @param bool $getGroups - search in groups
273
	 * @param bool $getUsers - search in site users
274
	 * @param bool $getContacts - search in contacs
275
	 * @param bool $getContactGroups - search in contacs
276
	 * @param array $skipGroups - group names to skip in return array
277
	 * @param array $skipUsers - user names to skip in return array
278
	 * @return Array
279
	 */
280
	public function getSiteUsersAndGroups(
281
		$query = '',
282
		$getGroups = true,
283
		$getUsers = true,
284
		$getContacts = true,
285
		$getContactGroups = true,
0 ignored issues
show
Unused Code introduced by
The parameter $getContactGroups is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

285
		/** @scrutinizer ignore-unused */ $getContactGroups = true,

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

Loading history...
286
		$getMail = false,
287
		$skipGroups = array(),
288
		$skipUsers = array()
289
	) {
290
		$list = array();
291
292
		if ($getMail && $this->isValidEmail($query)) {
293
			$list[] = [
294
				'id' => '',
295
				'user' => '',
296
				'organisation' => '',
297
				'displayName' => '',
298
				'emailAddress' => $query,
299
				'desc' => $query,
300
				'type' => 'email',
301
				'icon' => 'icon-mail',
302
				'avatarURL' => '',
303
				'avatar' => '',
304
				'lastLogin' => '',
305
				'cloudId' => ''
306
307
			];
308
		}
309
		if ($getGroups) {
310
			$list = array_merge($list, $this->getSiteGroups($query, $skipGroups));
311
		}
312
313
		if ($getUsers) {
314
			$list = array_merge($list, $this->getSiteUsers($query, $skipUsers));
315
		}
316
317
		if (\OC::$server->getContactsManager()->isEnabled()) {
318
			if ($getContacts) {
319
				$list = array_merge($list, $this->getContacts($query, $skipUsers));
0 ignored issues
show
Unused Code introduced by
The call to OCA\Polls\Service\SystemService::getContacts() has too many arguments starting with $skipUsers. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

319
				$list = array_merge($list, $this->/** @scrutinizer ignore-call */ getContacts($query, $skipUsers));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
320
			}
321
322
			if ($getContacts) {
323
				$list = array_merge($list, $this->getContactsGroups($query, $skipGroups));
0 ignored issues
show
Unused Code introduced by
The call to OCA\Polls\Service\System...ce::getContactsGroups() has too many arguments starting with $skipGroups. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

323
				$list = array_merge($list, $this->/** @scrutinizer ignore-call */ getContactsGroups($query, $skipGroups));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
324
			}
325
		}
326
327
		return $list;
328
	}
329
330
	/**
331
	 * Validate it the user name is reservrd
332
	 * return false, if this username already exists as a user or as
333
	 * a participant of the poll
334
	 * @NoAdminRequired
335
	 * @return Boolean
336
	 * @throws NotAuthorizedException
337
	 * @throws TooShortException
338
	 * @throws UsernameInvalidException
339
	 */
340
	public function validatePublicUsername($pollId, $userName, $token) {
341
342
		// return forbidden, if $pollId does not match the share's pollId, force int compare
343
		if (intval($this->shareMapper->findByToken($token)->getPollId()) !== intVal($pollId)) {
344
			throw new NotAuthorizedException;
345
		}
346
347
		// return forbidden, if the length of the userame is lower than 3 characters
348
		if (strlen(trim($userName)) < 3) {
349
			return new TooShortException('Username must have at least 3 characters');
350
		}
351
352
		$list = array();
353
354
		// get all groups
355
		$groups = $this->groupManager->search('');
356
		foreach ($groups as $group) {
357
			$list[] = [
358
				'id' => $group->getGID(),
359
				'user' => $group->getGID(),
360
				'type' => 'group',
361
				'displayName' => $group->getGID(),
362
			];
363
		}
364
365
		// get all users
366
		$users = $this->userManager->searchDisplayName('');
367
		foreach ($users as $user) {
368
			$list[] = [
369
				'id' => $user->getUID(),
370
				'user' => $user->getUID(),
371
				'type' => 'user',
372
				'displayName' => $user->getDisplayName(),
373
			];
374
		}
375
376
		// get all participants
377
		$votes = $this->voteMapper->findParticipantsByPoll($pollId);
378
		foreach ($votes as $vote) {
379
			if ($vote->getUserId() !== '' && $vote->getUserId() !== null) {
380
				$list[] = [
381
					'id' => $vote->getUserId(),
382
					'user' => $vote->getUserId(),
383
					'type' => 'participant',
384
					'displayName' => $vote->getUserId(),
385
				];
386
			}
387
		}
388
389
		// get all shares for this poll
390
		$shares = $this->shareMapper->findByPoll($pollId);
391
		foreach ($shares as $share) {
392
			if ($share->getUserId() !== '' && $share->getUserId() !== null) {
393
				$list[] = [
394
					'id' => $share->getUserId(),
395
					'user' => $share->getUserId(),
396
					'type' => 'share',
397
					'displayName' => $share->getUserId(),
398
				];
399
			}
400
		}
401
402
		// check if the username is contained inside the generated list
403
		// return forbidden, if list contains requested username
404
		foreach ($list as $element) {
405
			if (strtolower(trim($userName)) === strtolower(trim($element['id'])) || strtolower(trim($userName)) === strtolower(trim($element['displayName']))) {
406
				throw new UsernameInvalidException;
407
			}
408
		}
409
410
		// return true, if username is allowed
411
		return true;
412
	}
413
414
}
415