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

GroupPlugin   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 57
dl 0
loc 96
rs 10
c 0
b 0
f 0
wmc 21

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
D search() 0 75 19
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