Completed
Push — master ( 97f80f...3da92a )
by Morris
49:49 queued 34:18
created

MailPlugin::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 5
dl 10
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Arthur Schiwon <[email protected]>
4
 *
5
 * @author Arthur Schiwon <[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 OC\Collaboration\Collaborators;
25
26
27
use OCP\Collaboration\Collaborators\ISearchPlugin;
28
use OCP\Collaboration\Collaborators\ISearchResult;
29
use OCP\Collaboration\Collaborators\SearchResultType;
30
use OCP\Contacts\IManager;
31
use OCP\Federation\ICloudIdManager;
32
use OCP\IConfig;
33
use OCP\IGroupManager;
34
use OCP\IUserSession;
35
use OCP\Share;
36
37
class MailPlugin implements ISearchPlugin {
38
	protected $shareeEnumeration;
39
	protected $shareWithGroupOnly;
40
41
	/** @var IManager */
42
	private $contactsManager;
43
	/** @var ICloudIdManager */
44
	private $cloudIdManager;
45
	/** @var IConfig */
46
	private $config;
47
48
	/** @var IGroupManager */
49
	private $groupManager;
50
51
	/** @var IUserSession */
52
	private $userSession;
53
54 View Code Duplication
	public function __construct(IManager $contactsManager, ICloudIdManager $cloudIdManager, IConfig $config, IGroupManager $groupManager, IUserSession $userSession) {
55
		$this->contactsManager = $contactsManager;
56
		$this->cloudIdManager = $cloudIdManager;
57
		$this->config = $config;
58
		$this->groupManager = $groupManager;
59
		$this->userSession = $userSession;
60
61
		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
62
		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
63
	}
64
65
	/**
66
	 * @param $search
67
	 * @param $limit
68
	 * @param $offset
69
	 * @param ISearchResult $searchResult
70
	 * @return bool
71
	 * @since 13.0.0
72
	 */
73
	public function search($search, $limit, $offset, ISearchResult $searchResult) {
74
		$result = ['wide' => [], 'exact' => []];
75
		$userType = new SearchResultType('users');
76
		$emailType = new SearchResultType('emails');
77
78
		// Search in contacts
79
		//@todo Pagination missing
80
		$addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
81
		$lowerSearch = strtolower($search);
82
		foreach ($addressBookContacts as $contact) {
83
			if (isset($contact['EMAIL'])) {
84
				$emailAddresses = $contact['EMAIL'];
85
				if (!is_array($emailAddresses)) {
86
					$emailAddresses = [$emailAddresses];
87
				}
88
				foreach ($emailAddresses as $emailAddress) {
89
					$exactEmailMatch = strtolower($emailAddress) === $lowerSearch;
90
91
					if (isset($contact['isLocalSystemBook'])) {
92
						if ($this->shareWithGroupOnly) {
93
							/*
94
							 * Check if the user may share with the user associated with the e-mail of the just found contact
95
							 */
96
							$userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
0 ignored issues
show
Bug introduced by
It seems like $this->userSession->getUser() can be null; however, getUserGroupIds() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
97
							$found = false;
98
							foreach ($userGroups as $userGroup) {
99
								if ($this->groupManager->isInGroup($contact['UID'], $userGroup)) {
100
									$found = true;
101
									break;
102
								}
103
							}
104
							if (!$found) {
105
								continue;
106
							}
107
						}
108
						if ($exactEmailMatch) {
109
							try {
110
								$cloud = $this->cloudIdManager->resolveCloudId($contact['CLOUD'][0]);
111
							} catch (\InvalidArgumentException $e) {
112
								continue;
113
							}
114
115 View Code Duplication
							if (!$searchResult->hasResult($userType, $cloud->getUser())) {
116
								$singleResult = [[
117
									'label' => $contact['FN'] . " ($emailAddress)",
118
									'value' => [
119
										'shareType' => Share::SHARE_TYPE_USER,
120
										'shareWith' => $cloud->getUser(),
121
									],
122
								]];
123
								$searchResult->addResultSet($userType, [], $singleResult);
124
								$searchResult->markExactIdMatch($emailType);
125
							}
126
							return false;
127
						}
128
129
						if ($this->shareeEnumeration) {
130
							try {
131
								$cloud = $this->cloudIdManager->resolveCloudId($contact['CLOUD'][0]);
132
							} catch (\InvalidArgumentException $e) {
133
								continue;
134
							}
135
136 View Code Duplication
							if (!$searchResult->hasResult($userType, $cloud->getUser())) {
137
								$singleResult = [[
138
									'label' => $contact['FN'] . " ($emailAddress)",
139
									'value' => [
140
										'shareType' => Share::SHARE_TYPE_USER,
141
										'shareWith' => $cloud->getUser(),
142
									]],
143
								];
144
								$searchResult->addResultSet($userType, $singleResult, []);
145
							}
146
						}
147
						continue;
148
					}
149
150
					if ($exactEmailMatch || strtolower($contact['FN']) === $lowerSearch) {
151
						if ($exactEmailMatch) {
152
							$searchResult->markExactIdMatch($emailType);
153
						}
154
						$result['exact'][] = [
155
							'label' => $contact['FN'] . " ($emailAddress)",
156
							'value' => [
157
								'shareType' => Share::SHARE_TYPE_EMAIL,
158
								'shareWith' => $emailAddress,
159
							],
160
						];
161 View Code Duplication
					} else {
162
						$result['wide'][] = [
163
							'label' => $contact['FN'] . " ($emailAddress)",
164
							'value' => [
165
								'shareType' => Share::SHARE_TYPE_EMAIL,
166
								'shareWith' => $emailAddress,
167
							],
168
						];
169
					}
170
				}
171
			}
172
		}
173
174
		if (!$this->shareeEnumeration) {
175
			$result['wide'] = [];
176
		}
177
178
		if (!$searchResult->hasExactIdMatch($emailType) && filter_var($search, FILTER_VALIDATE_EMAIL)) {
179
			$result['exact'][] = [
180
				'label' => $search,
181
				'value' => [
182
					'shareType' => Share::SHARE_TYPE_EMAIL,
183
					'shareWith' => $search,
184
				],
185
			];
186
		}
187
188
		$searchResult->addResultSet($emailType, $result['wide'], $result['exact']);
189
190
		return true;
191
	}
192
}
193