Passed
Push — master ( 581704...2efa00 )
by Roeland
11:12 queued 11s
created

GroupPlugin::search()   D

Complexity

Conditions 19
Paths 144

Size

Total Lines 75
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 45
nc 144
nop 4
dl 0
loc 75
rs 4.1499
c 0
b 0
f 0

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
 * @copyright Copyright (c) 2017 Arthur Schiwon <[email protected]>
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Robin Appelman <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OC\Collaboration\Collaborators;
27
28
use OCP\Collaboration\Collaborators\ISearchPlugin;
29
use OCP\Collaboration\Collaborators\ISearchResult;
30
use OCP\Collaboration\Collaborators\SearchResultType;
31
use OCP\IConfig;
32
use OCP\IGroup;
33
use OCP\IGroupManager;
34
use OCP\IUserSession;
35
use OCP\Share;
36
37
class GroupPlugin implements ISearchPlugin {
38
	protected $shareeEnumeration;
39
	protected $shareWithGroupOnly;
40
41
	/** @var IGroupManager */
42
	private $groupManager;
43
	/** @var IConfig */
44
	private $config;
45
	/** @var IUserSession */
46
	private $userSession;
47
48
	public function __construct(IConfig $config, IGroupManager $groupManager, IUserSession $userSession) {
49
		$this->groupManager = $groupManager;
50
		$this->config = $config;
51
		$this->userSession = $userSession;
52
53
		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
54
		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
55
		$this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
0 ignored issues
show
Bug Best Practice introduced by
The property shareeEnumerationInGroupOnly does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
56
	}
57
58
	public function search($search, $limit, $offset, ISearchResult $searchResult) {
59
		$hasMoreResults = false;
60
		$result = ['wide' => [], 'exact' => []];
61
62
		$groups = $this->groupManager->search($search, $limit, $offset);
63
		$groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
64
65
		if (!$this->shareeEnumeration || count($groups) < $limit) {
66
			$hasMoreResults = true;
67
		}
68
69
		$userGroups =  [];
70
		if (!empty($groups) && ($this->shareWithGroupOnly || $this->shareeEnumerationInGroupOnly)) {
71
			// Intersect all the groups that match with the groups this user is a member of
72
			$userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
73
			$userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
74
			$groupIds = array_intersect($groupIds, $userGroups);
75
		}
76
77
		$lowerSearch = strtolower($search);
78
		foreach ($groups as $group) {
79
			if ($group->hideFromCollaboration()) {
80
				continue;
81
			}
82
83
			// FIXME: use a more efficient approach
84
			$gid = $group->getGID();
85
			if (!in_array($gid, $groupIds)) {
86
				continue;
87
			}
88
			if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
89
				$result['exact'][] = [
90
					'label' => $group->getDisplayName(),
91
					'value' => [
92
						'shareType' => Share::SHARE_TYPE_GROUP,
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

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

92
						'shareType' => /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP,

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
93
						'shareWith' => $gid,
94
					],
95
				];
96
			} else {
97
				if ($this->shareeEnumerationInGroupOnly && !in_array($group->getGID(), $userGroups, true)) {
98
					continue;
99
				}
100
				$result['wide'][] = [
101
					'label' => $group->getDisplayName(),
102
					'value' => [
103
						'shareType' => Share::SHARE_TYPE_GROUP,
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

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

103
						'shareType' => /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP,

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
104
						'shareWith' => $gid,
105
					],
106
				];
107
			}
108
		}
109
110
		if ($offset === 0 && empty($result['exact'])) {
111
			// On page one we try if the search result has a direct hit on the
112
			// user id and if so, we add that to the exact match list
113
			$group = $this->groupManager->get($search);
114
			if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
115
				$result['exact'][] = [
116
					'label' => $group->getDisplayName(),
117
					'value' => [
118
						'shareType' => Share::SHARE_TYPE_GROUP,
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

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

118
						'shareType' => /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP,

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
119
						'shareWith' => $group->getGID(),
120
					],
121
				];
122
			}
123
		}
124
125
		if (!$this->shareeEnumeration) {
126
			$result['wide'] = [];
127
		}
128
129
		$type = new SearchResultType('groups');
130
		$searchResult->addResultSet($type, $result['wide'], $result['exact']);
131
132
		return $hasMoreResults;
133
	}
134
}
135