Passed
Push — master ( a178d6...7d024b )
by Blizzz
14:27 queued 12s
created
lib/private/Contacts/ContactsMenu/ContactsStore.php 1 patch
Indentation   +280 added lines, -280 removed lines patch added patch discarded remove patch
@@ -44,284 +44,284 @@
 block discarded – undo
44 44
 use OCP\L10N\IFactory as IL10NFactory;
45 45
 
46 46
 class ContactsStore implements IContactsStore {
47
-	private IManager $contactsManager;
48
-	private IConfig $config;
49
-	private ProfileManager $profileManager;
50
-	private IUserManager $userManager;
51
-	private IURLGenerator $urlGenerator;
52
-	private IGroupManager $groupManager;
53
-	private KnownUserService $knownUserService;
54
-	private IL10NFactory $l10nFactory;
55
-
56
-	public function __construct(
57
-		IManager $contactsManager,
58
-		IConfig $config,
59
-		ProfileManager $profileManager,
60
-		IUserManager $userManager,
61
-		IURLGenerator $urlGenerator,
62
-		IGroupManager $groupManager,
63
-		KnownUserService $knownUserService,
64
-		IL10NFactory $l10nFactory
65
-	) {
66
-		$this->contactsManager = $contactsManager;
67
-		$this->config = $config;
68
-		$this->profileManager = $profileManager;
69
-		$this->userManager = $userManager;
70
-		$this->urlGenerator = $urlGenerator;
71
-		$this->groupManager = $groupManager;
72
-		$this->knownUserService = $knownUserService;
73
-		$this->l10nFactory = $l10nFactory;
74
-	}
75
-
76
-	/**
77
-	 * @return IEntry[]
78
-	 */
79
-	public function getContacts(IUser $user, ?string $filter, ?int $limit = null, ?int $offset = null): array {
80
-		$options = [
81
-			'enumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes',
82
-			'fullmatch' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes',
83
-		];
84
-		if ($limit !== null) {
85
-			$options['limit'] = $limit;
86
-		}
87
-		if ($offset !== null) {
88
-			$options['offset'] = $offset;
89
-		}
90
-
91
-		$allContacts = $this->contactsManager->search(
92
-			$filter ?? '',
93
-			[
94
-				'FN',
95
-				'EMAIL'
96
-			],
97
-			$options
98
-		);
99
-
100
-		$userId = $user->getUID();
101
-		$contacts = array_filter($allContacts, function ($contact) use ($userId) {
102
-			// When searching for multiple results, we strip out the current user
103
-			if (array_key_exists('UID', $contact)) {
104
-				return $contact['UID'] !== $userId;
105
-			}
106
-			return true;
107
-		});
108
-
109
-		$entries = array_map(function (array $contact) {
110
-			return $this->contactArrayToEntry($contact);
111
-		}, $contacts);
112
-		return $this->filterContacts(
113
-			$user,
114
-			$entries,
115
-			$filter
116
-		);
117
-	}
118
-
119
-	/**
120
-	 * Filters the contacts. Applied filters:
121
-	 *  1. if the `shareapi_allow_share_dialog_user_enumeration` config option is
122
-	 * enabled it will filter all local users
123
-	 *  2. if the `shareapi_exclude_groups` config option is enabled and the
124
-	 * current user is in an excluded group it will filter all local users.
125
-	 *  3. if the `shareapi_only_share_with_group_members` config option is
126
-	 * enabled it will filter all users which doesn't have a common group
127
-	 * with the current user.
128
-	 *
129
-	 * @param IUser $self
130
-	 * @param Entry[] $entries
131
-	 * @param string|null $filter
132
-	 * @return Entry[] the filtered contacts
133
-	 */
134
-	private function filterContacts(
135
-		IUser $self,
136
-		array $entries,
137
-		?string $filter
138
-	): array {
139
-		$disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
140
-		$restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
141
-		$restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
142
-		$allowEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
143
-		$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes';
144
-
145
-		// whether to filter out local users
146
-		$skipLocal = false;
147
-		// whether to filter out all users which don't have a common group as the current user
148
-		$ownGroupsOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
149
-
150
-		$selfGroups = $this->groupManager->getUserGroupIds($self);
151
-
152
-		if ($excludedGroups) {
153
-			$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
154
-			$decodedExcludeGroups = json_decode($excludedGroups, true);
155
-			$excludeGroupsList = $decodedExcludeGroups ?? [];
156
-
157
-			if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
158
-				// a group of the current user is excluded -> filter all local users
159
-				$skipLocal = true;
160
-			}
161
-		}
162
-
163
-		$selfUID = $self->getUID();
164
-
165
-		return array_values(array_filter($entries, function (IEntry $entry) use ($skipLocal, $ownGroupsOnly, $selfGroups, $selfUID, $disallowEnumeration, $restrictEnumerationGroup, $restrictEnumerationPhone, $allowEnumerationFullMatch, $filter) {
166
-			if ($entry->getProperty('isLocalSystemBook')) {
167
-				if ($skipLocal) {
168
-					return false;
169
-				}
170
-
171
-				$checkedCommonGroupAlready = false;
172
-
173
-				// Prevent enumerating local users
174
-				if ($disallowEnumeration) {
175
-					if (!$allowEnumerationFullMatch) {
176
-						return false;
177
-					}
178
-
179
-					$filterOutUser = true;
180
-
181
-					$mailAddresses = $entry->getEMailAddresses();
182
-					foreach ($mailAddresses as $mailAddress) {
183
-						if ($mailAddress === $filter) {
184
-							$filterOutUser = false;
185
-							break;
186
-						}
187
-					}
188
-
189
-					if ($entry->getProperty('UID') && $entry->getProperty('UID') === $filter) {
190
-						$filterOutUser = false;
191
-					}
192
-
193
-					if ($filterOutUser) {
194
-						return false;
195
-					}
196
-				} elseif ($restrictEnumerationPhone || $restrictEnumerationGroup) {
197
-					$canEnumerate = false;
198
-					if ($restrictEnumerationPhone) {
199
-						$canEnumerate = $this->knownUserService->isKnownToUser($selfUID, $entry->getProperty('UID'));
200
-					}
201
-
202
-					if (!$canEnumerate && $restrictEnumerationGroup) {
203
-						$user = $this->userManager->get($entry->getProperty('UID'));
204
-
205
-						if ($user === null) {
206
-							return false;
207
-						}
208
-
209
-						$contactGroups = $this->groupManager->getUserGroupIds($user);
210
-						$canEnumerate = !empty(array_intersect($contactGroups, $selfGroups));
211
-						$checkedCommonGroupAlready = true;
212
-					}
213
-
214
-					if (!$canEnumerate) {
215
-						return false;
216
-					}
217
-				}
218
-
219
-				if ($ownGroupsOnly && !$checkedCommonGroupAlready) {
220
-					$user = $this->userManager->get($entry->getProperty('UID'));
221
-
222
-					if (!$user instanceof IUser) {
223
-						return false;
224
-					}
225
-
226
-					$contactGroups = $this->groupManager->getUserGroupIds($user);
227
-					if (empty(array_intersect($contactGroups, $selfGroups))) {
228
-						// no groups in common, so shouldn't see the contact
229
-						return false;
230
-					}
231
-				}
232
-			}
233
-
234
-			return true;
235
-		}));
236
-	}
237
-
238
-	public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry {
239
-		switch ($shareType) {
240
-			case 0:
241
-			case 6:
242
-				$filter = ['UID'];
243
-				break;
244
-			case 4:
245
-				$filter = ['EMAIL'];
246
-				break;
247
-			default:
248
-				return null;
249
-		}
250
-
251
-		$contacts = $this->contactsManager->search($shareWith, $filter, [
252
-			'strict_search' => true,
253
-		]);
254
-		$match = null;
255
-
256
-		foreach ($contacts as $contact) {
257
-			if ($shareType === 4 && isset($contact['EMAIL'])) {
258
-				if (in_array($shareWith, $contact['EMAIL'])) {
259
-					$match = $contact;
260
-					break;
261
-				}
262
-			}
263
-			if ($shareType === 0 || $shareType === 6) {
264
-				$isLocal = $contact['isLocalSystemBook'] ?? false;
265
-				if ($contact['UID'] === $shareWith && $isLocal === true) {
266
-					$match = $contact;
267
-					break;
268
-				}
269
-			}
270
-		}
271
-
272
-		if ($match) {
273
-			$match = $this->filterContacts($user, [$this->contactArrayToEntry($match)], $shareWith);
274
-			if (count($match) === 1) {
275
-				$match = $match[0];
276
-			} else {
277
-				$match = null;
278
-			}
279
-		}
280
-
281
-		return $match;
282
-	}
283
-
284
-	private function contactArrayToEntry(array $contact): Entry {
285
-		$entry = new Entry();
286
-
287
-		if (isset($contact['UID'])) {
288
-			$uid = $contact['UID'];
289
-			$entry->setId($uid);
290
-			$avatar = $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $uid, 'size' => 64]);
291
-			$entry->setAvatar($avatar);
292
-		}
293
-
294
-		if (isset($contact['FN'])) {
295
-			$entry->setFullName($contact['FN']);
296
-		}
297
-
298
-		$avatarPrefix = "VALUE=uri:";
299
-		if (isset($contact['PHOTO']) && strpos($contact['PHOTO'], $avatarPrefix) === 0) {
300
-			$entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix)));
301
-		}
302
-
303
-		if (isset($contact['EMAIL'])) {
304
-			foreach ($contact['EMAIL'] as $email) {
305
-				$entry->addEMailAddress($email);
306
-			}
307
-		}
308
-
309
-		// Provide profile parameters for core/src/OC/contactsmenu/contact.handlebars template
310
-		if (isset($contact['UID']) && isset($contact['FN'])) {
311
-			$targetUserId = $contact['UID'];
312
-			$targetUser = $this->userManager->get($targetUserId);
313
-			if (!empty($targetUser)) {
314
-				if ($this->profileManager->isProfileEnabled($targetUser)) {
315
-					$entry->setProfileTitle($this->l10nFactory->get('lib')->t('View profile'));
316
-					$entry->setProfileUrl($this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $targetUserId]));
317
-				}
318
-			}
319
-		}
320
-
321
-		// Attach all other properties to the entry too because some
322
-		// providers might make use of it.
323
-		$entry->setProperties($contact);
324
-
325
-		return $entry;
326
-	}
47
+    private IManager $contactsManager;
48
+    private IConfig $config;
49
+    private ProfileManager $profileManager;
50
+    private IUserManager $userManager;
51
+    private IURLGenerator $urlGenerator;
52
+    private IGroupManager $groupManager;
53
+    private KnownUserService $knownUserService;
54
+    private IL10NFactory $l10nFactory;
55
+
56
+    public function __construct(
57
+        IManager $contactsManager,
58
+        IConfig $config,
59
+        ProfileManager $profileManager,
60
+        IUserManager $userManager,
61
+        IURLGenerator $urlGenerator,
62
+        IGroupManager $groupManager,
63
+        KnownUserService $knownUserService,
64
+        IL10NFactory $l10nFactory
65
+    ) {
66
+        $this->contactsManager = $contactsManager;
67
+        $this->config = $config;
68
+        $this->profileManager = $profileManager;
69
+        $this->userManager = $userManager;
70
+        $this->urlGenerator = $urlGenerator;
71
+        $this->groupManager = $groupManager;
72
+        $this->knownUserService = $knownUserService;
73
+        $this->l10nFactory = $l10nFactory;
74
+    }
75
+
76
+    /**
77
+     * @return IEntry[]
78
+     */
79
+    public function getContacts(IUser $user, ?string $filter, ?int $limit = null, ?int $offset = null): array {
80
+        $options = [
81
+            'enumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes',
82
+            'fullmatch' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes',
83
+        ];
84
+        if ($limit !== null) {
85
+            $options['limit'] = $limit;
86
+        }
87
+        if ($offset !== null) {
88
+            $options['offset'] = $offset;
89
+        }
90
+
91
+        $allContacts = $this->contactsManager->search(
92
+            $filter ?? '',
93
+            [
94
+                'FN',
95
+                'EMAIL'
96
+            ],
97
+            $options
98
+        );
99
+
100
+        $userId = $user->getUID();
101
+        $contacts = array_filter($allContacts, function ($contact) use ($userId) {
102
+            // When searching for multiple results, we strip out the current user
103
+            if (array_key_exists('UID', $contact)) {
104
+                return $contact['UID'] !== $userId;
105
+            }
106
+            return true;
107
+        });
108
+
109
+        $entries = array_map(function (array $contact) {
110
+            return $this->contactArrayToEntry($contact);
111
+        }, $contacts);
112
+        return $this->filterContacts(
113
+            $user,
114
+            $entries,
115
+            $filter
116
+        );
117
+    }
118
+
119
+    /**
120
+     * Filters the contacts. Applied filters:
121
+     *  1. if the `shareapi_allow_share_dialog_user_enumeration` config option is
122
+     * enabled it will filter all local users
123
+     *  2. if the `shareapi_exclude_groups` config option is enabled and the
124
+     * current user is in an excluded group it will filter all local users.
125
+     *  3. if the `shareapi_only_share_with_group_members` config option is
126
+     * enabled it will filter all users which doesn't have a common group
127
+     * with the current user.
128
+     *
129
+     * @param IUser $self
130
+     * @param Entry[] $entries
131
+     * @param string|null $filter
132
+     * @return Entry[] the filtered contacts
133
+     */
134
+    private function filterContacts(
135
+        IUser $self,
136
+        array $entries,
137
+        ?string $filter
138
+    ): array {
139
+        $disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
140
+        $restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
141
+        $restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
142
+        $allowEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
143
+        $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes';
144
+
145
+        // whether to filter out local users
146
+        $skipLocal = false;
147
+        // whether to filter out all users which don't have a common group as the current user
148
+        $ownGroupsOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
149
+
150
+        $selfGroups = $this->groupManager->getUserGroupIds($self);
151
+
152
+        if ($excludedGroups) {
153
+            $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
154
+            $decodedExcludeGroups = json_decode($excludedGroups, true);
155
+            $excludeGroupsList = $decodedExcludeGroups ?? [];
156
+
157
+            if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
158
+                // a group of the current user is excluded -> filter all local users
159
+                $skipLocal = true;
160
+            }
161
+        }
162
+
163
+        $selfUID = $self->getUID();
164
+
165
+        return array_values(array_filter($entries, function (IEntry $entry) use ($skipLocal, $ownGroupsOnly, $selfGroups, $selfUID, $disallowEnumeration, $restrictEnumerationGroup, $restrictEnumerationPhone, $allowEnumerationFullMatch, $filter) {
166
+            if ($entry->getProperty('isLocalSystemBook')) {
167
+                if ($skipLocal) {
168
+                    return false;
169
+                }
170
+
171
+                $checkedCommonGroupAlready = false;
172
+
173
+                // Prevent enumerating local users
174
+                if ($disallowEnumeration) {
175
+                    if (!$allowEnumerationFullMatch) {
176
+                        return false;
177
+                    }
178
+
179
+                    $filterOutUser = true;
180
+
181
+                    $mailAddresses = $entry->getEMailAddresses();
182
+                    foreach ($mailAddresses as $mailAddress) {
183
+                        if ($mailAddress === $filter) {
184
+                            $filterOutUser = false;
185
+                            break;
186
+                        }
187
+                    }
188
+
189
+                    if ($entry->getProperty('UID') && $entry->getProperty('UID') === $filter) {
190
+                        $filterOutUser = false;
191
+                    }
192
+
193
+                    if ($filterOutUser) {
194
+                        return false;
195
+                    }
196
+                } elseif ($restrictEnumerationPhone || $restrictEnumerationGroup) {
197
+                    $canEnumerate = false;
198
+                    if ($restrictEnumerationPhone) {
199
+                        $canEnumerate = $this->knownUserService->isKnownToUser($selfUID, $entry->getProperty('UID'));
200
+                    }
201
+
202
+                    if (!$canEnumerate && $restrictEnumerationGroup) {
203
+                        $user = $this->userManager->get($entry->getProperty('UID'));
204
+
205
+                        if ($user === null) {
206
+                            return false;
207
+                        }
208
+
209
+                        $contactGroups = $this->groupManager->getUserGroupIds($user);
210
+                        $canEnumerate = !empty(array_intersect($contactGroups, $selfGroups));
211
+                        $checkedCommonGroupAlready = true;
212
+                    }
213
+
214
+                    if (!$canEnumerate) {
215
+                        return false;
216
+                    }
217
+                }
218
+
219
+                if ($ownGroupsOnly && !$checkedCommonGroupAlready) {
220
+                    $user = $this->userManager->get($entry->getProperty('UID'));
221
+
222
+                    if (!$user instanceof IUser) {
223
+                        return false;
224
+                    }
225
+
226
+                    $contactGroups = $this->groupManager->getUserGroupIds($user);
227
+                    if (empty(array_intersect($contactGroups, $selfGroups))) {
228
+                        // no groups in common, so shouldn't see the contact
229
+                        return false;
230
+                    }
231
+                }
232
+            }
233
+
234
+            return true;
235
+        }));
236
+    }
237
+
238
+    public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry {
239
+        switch ($shareType) {
240
+            case 0:
241
+            case 6:
242
+                $filter = ['UID'];
243
+                break;
244
+            case 4:
245
+                $filter = ['EMAIL'];
246
+                break;
247
+            default:
248
+                return null;
249
+        }
250
+
251
+        $contacts = $this->contactsManager->search($shareWith, $filter, [
252
+            'strict_search' => true,
253
+        ]);
254
+        $match = null;
255
+
256
+        foreach ($contacts as $contact) {
257
+            if ($shareType === 4 && isset($contact['EMAIL'])) {
258
+                if (in_array($shareWith, $contact['EMAIL'])) {
259
+                    $match = $contact;
260
+                    break;
261
+                }
262
+            }
263
+            if ($shareType === 0 || $shareType === 6) {
264
+                $isLocal = $contact['isLocalSystemBook'] ?? false;
265
+                if ($contact['UID'] === $shareWith && $isLocal === true) {
266
+                    $match = $contact;
267
+                    break;
268
+                }
269
+            }
270
+        }
271
+
272
+        if ($match) {
273
+            $match = $this->filterContacts($user, [$this->contactArrayToEntry($match)], $shareWith);
274
+            if (count($match) === 1) {
275
+                $match = $match[0];
276
+            } else {
277
+                $match = null;
278
+            }
279
+        }
280
+
281
+        return $match;
282
+    }
283
+
284
+    private function contactArrayToEntry(array $contact): Entry {
285
+        $entry = new Entry();
286
+
287
+        if (isset($contact['UID'])) {
288
+            $uid = $contact['UID'];
289
+            $entry->setId($uid);
290
+            $avatar = $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $uid, 'size' => 64]);
291
+            $entry->setAvatar($avatar);
292
+        }
293
+
294
+        if (isset($contact['FN'])) {
295
+            $entry->setFullName($contact['FN']);
296
+        }
297
+
298
+        $avatarPrefix = "VALUE=uri:";
299
+        if (isset($contact['PHOTO']) && strpos($contact['PHOTO'], $avatarPrefix) === 0) {
300
+            $entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix)));
301
+        }
302
+
303
+        if (isset($contact['EMAIL'])) {
304
+            foreach ($contact['EMAIL'] as $email) {
305
+                $entry->addEMailAddress($email);
306
+            }
307
+        }
308
+
309
+        // Provide profile parameters for core/src/OC/contactsmenu/contact.handlebars template
310
+        if (isset($contact['UID']) && isset($contact['FN'])) {
311
+            $targetUserId = $contact['UID'];
312
+            $targetUser = $this->userManager->get($targetUserId);
313
+            if (!empty($targetUser)) {
314
+                if ($this->profileManager->isProfileEnabled($targetUser)) {
315
+                    $entry->setProfileTitle($this->l10nFactory->get('lib')->t('View profile'));
316
+                    $entry->setProfileUrl($this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $targetUserId]));
317
+                }
318
+            }
319
+        }
320
+
321
+        // Attach all other properties to the entry too because some
322
+        // providers might make use of it.
323
+        $entry->setProperties($contact);
324
+
325
+        return $entry;
326
+    }
327 327
 }
Please login to merge, or discard this patch.