2828use OCP \IConfig ;
2929use OCP \IGroupManager ;
3030use OCP \IUserManager ;
31+ use function is_array ;
3132
3233class ContactsIntegration {
3334 /** @var IManager */
@@ -60,55 +61,9 @@ public function __construct(IManager $contactsManager,
6061 * @return array
6162 */
6263 public function getMatchingRecipient (string $ userId , string $ term ): array {
63- if (!$ this ->contactsManager ->isEnabled ()) {
64- return [];
65- }
66-
67- // If 'Allow username autocompletion in share dialog' is disabled in the admin sharing settings, then we must not
68- // auto-complete system users
69- $ shareeEnumeration = $ this ->config ->getAppValue ('core ' , 'shareapi_allow_share_dialog_user_enumeration ' , 'no ' ) === 'yes ' ;
70- $ shareeEnumerationInGroupOnly = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_to_group ' , 'no ' ) === 'yes ' ;
71- $ shareeEnumerationFullMatch = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match ' , 'yes ' ) === 'yes ' ;
72- $ shareeEnumerationFullMatchUserId = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_userid ' , 'yes ' ) === 'yes ' ;
73- $ shareeEnumerationFullMatchEmail = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_email ' , 'yes ' ) === 'yes ' ;
74-
75- $ result = $ this ->contactsManager ->search (
76- $ term ,
77- ['UID ' , 'FN ' , 'EMAIL ' ],
78- [
79- 'enumeration ' => $ shareeEnumeration ,
80- 'fullmatch ' => $ shareeEnumerationFullMatch ,
81- 'limit ' => 20 ,
82- ],
83- );
84- if (empty ($ result )) {
85- return [];
86- }
64+ $ result = $ this ->search ($ userId , $ term , ['UID ' , 'FN ' , 'EMAIL ' ]);
8765 $ receivers = [];
88-
89- if ($ shareeEnumeration && $ shareeEnumerationInGroupOnly ) {
90- $ user = $ this ->userManager ->get ($ userId );
91- if ($ user === null ) {
92- return [];
93- }
94- $ userGroups = $ this ->groupManager ->getUserGroupIds ($ user );
95- }
96-
9766 foreach ($ result as $ r ) {
98- $ isSystemUser = isset ($ r ['isLocalSystemBook ' ]) && $ r ['isLocalSystemBook ' ];
99- $ isInSameGroup = false ;
100- if ($ isSystemUser && $ shareeEnumerationInGroupOnly ) {
101- foreach ($ userGroups as $ userGroup ) {
102- if ($ this ->groupManager ->isInGroup ($ r ['UID ' ], $ userGroup )) {
103- $ isInSameGroup = true ;
104- break ;
105- }
106- }
107- if (!$ shareeEnumerationFullMatch && !$ isInSameGroup ) {
108- continue ;
109- }
110- }
111-
11267 $ id = $ r ['UID ' ];
11368 $ fn = $ r ['FN ' ] ?? null ;
11469 if (!isset ($ r ['EMAIL ' ])) {
@@ -125,23 +80,10 @@ public function getMatchingRecipient(string $userId, string $term): array {
12580 if ($ e === '' ) {
12681 continue ;
12782 }
128- $ lowerTerm = strtolower ($ term );
129-
130- if ($ isSystemUser && $ shareeEnumerationInGroupOnly && !$ isInSameGroup ) {
131- // Check for full match. If full match is disabled, matching results already filtered out
132- if (!($ lowerTerm !== '' && (
133- ($ shareeEnumerationFullMatch && !empty ($ fn ) && $ lowerTerm === strtolower ($ fn )) ||
134- ($ shareeEnumerationFullMatchUserId && $ lowerTerm === strtolower ($ id )) ||
135- ($ shareeEnumerationFullMatchEmail && $ lowerTerm === strtolower ($ e ))))) {
136- // Not a full Match
137- continue ;
138- }
139- }
140-
14183 $ receivers [] = [
14284 'id ' => $ id ,
14385 // Show full name if possible or fall back to email
144- 'label ' => $ fn ,
86+ 'label ' => $ fn ?? $ e ,
14587 'email ' => $ e ,
14688 'photo ' => $ photo ,
14789 'source ' => 'contacts ' ,
@@ -243,21 +185,98 @@ public function newContact(string $name, string $mailAddr, string $type = 'HOME'
243185 return $ createdContact ;
244186 }
245187
188+ private function search (string $ userId , string $ term , array $ fields , ?bool $ strictSearch = null ): array {
189+ if (!$ this ->contactsManager ->isEnabled ()) {
190+ return [];
191+ }
192+
193+ // If 'Allow username autocompletion in share dialog' is disabled in the admin sharing settings, then we must not
194+ // auto-complete system users
195+ $ shareeEnumeration = $ this ->config ->getAppValue ('core ' , 'shareapi_allow_share_dialog_user_enumeration ' , 'yes ' ) === 'yes ' ;
196+ $ shareeEnumerationInGroupOnly = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_to_group ' , 'no ' ) === 'yes ' ;
197+ $ shareeEnumerationFullMatch = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match ' , 'yes ' ) === 'yes ' ;
198+ $ shareeEnumerationFullMatchDisplayName = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_displayname ' , 'yes ' ) === 'yes ' ;
199+ $ shareeEnumerationFullMatchUserId = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_userid ' , 'yes ' ) === 'yes ' ;
200+ $ shareeEnumerationFullMatchEmail = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_email ' , 'yes ' ) === 'yes ' ;
201+
202+ $ options = [
203+ 'enumeration ' => $ shareeEnumeration ,
204+ 'fullmatch ' => $ shareeEnumerationFullMatch ,
205+ 'limit ' => 20 ,
206+ ];
207+ if ($ strictSearch !== null ) {
208+ $ options ['strict_search ' ] = $ strictSearch ;
209+ }
210+
211+ $ result = $ this ->contactsManager ->search (
212+ $ term ,
213+ $ fields ,
214+ $ options ,
215+ );
216+
217+ $ userGroups = [];
218+ if ($ shareeEnumeration && $ shareeEnumerationInGroupOnly ) {
219+ $ user = $ this ->userManager ->get ($ userId );
220+ if ($ user === null ) {
221+ return [];
222+ }
223+ $ userGroups = $ this ->groupManager ->getUserGroupIds ($ user );
224+ }
225+
226+ $ filteredResults = [];
227+ foreach ($ result as $ r ) {
228+ $ isSystemUser = isset ($ r ['isLocalSystemBook ' ]) && $ r ['isLocalSystemBook ' ];
229+ $ isInSameGroup = false ;
230+ if ($ isSystemUser && $ shareeEnumerationInGroupOnly ) {
231+ foreach ($ userGroups as $ userGroup ) {
232+ if ($ this ->groupManager ->isInGroup ($ r ['UID ' ], $ userGroup )) {
233+ $ isInSameGroup = true ;
234+ break ;
235+ }
236+ }
237+ if (!$ shareeEnumerationFullMatch && !$ isInSameGroup ) {
238+ continue ;
239+ }
240+ }
241+
242+ if ($ isSystemUser && $ shareeEnumerationInGroupOnly && !$ isInSameGroup && $ shareeEnumerationFullMatch ) {
243+ // Check for full match. If full match is disabled, non-matching results already filtered out above.
244+ $ id = $ r ['UID ' ];
245+ $ fn = $ r ['FN ' ] ?? null ;
246+ $ lowerTerm = strtolower ($ term );
247+ $ isMatch = ($ lowerTerm !== '' && (
248+ ($ shareeEnumerationFullMatchDisplayName && !empty ($ fn ) && $ lowerTerm === strtolower ($ fn ))
249+ || ($ shareeEnumerationFullMatchUserId && $ lowerTerm === strtolower ($ id )))) ;
250+ if ($ shareeEnumerationFullMatchEmail && !$ isMatch ) {
251+ $ email = $ r ['EMAIL ' ] ?? null ;
252+ if ($ email === null ) {
253+ continue ;
254+ }
255+ $ emails = is_array ($ email ) ? $ email : [$ email ];
256+ foreach ($ emails as $ e ) {
257+ if ($ lowerTerm === strtolower ($ e )) {
258+ $ isMatch = true ;
259+ break ;
260+ }
261+ }
262+ }
263+ if (!$ isMatch ) {
264+ continue ;
265+ }
266+ }
267+
268+ $ filteredResults [] = $ r ;
269+ }
270+ return $ filteredResults ;
271+ }
272+
246273 /**
247274 * @param string[] $fields
248275 */
249- private function doSearch (string $ term , array $ fields , bool $ strictSearch ): array {
250- $ allowSystemUsers = $ this ->config ->getAppValue ('core ' , 'shareapi_allow_share_dialog_user_enumeration ' , 'no ' ) === 'yes ' ;
251-
252- $ result = $ this ->contactsManager ->search ($ term , $ fields , [
253- 'strict_search ' => $ strictSearch ,
254- 'limit ' => 20 ,
255- ]);
276+ private function doSearch (string $ userId , string $ term , array $ fields , bool $ strictSearch ) : array {
277+ $ result = $ this ->search ($ userId , $ term , $ fields , $ strictSearch );
256278 $ matches = [];
257279 foreach ($ result as $ r ) {
258- if (!$ allowSystemUsers && isset ($ r ['isLocalSystemBook ' ]) && $ r ['isLocalSystemBook ' ]) {
259- continue ;
260- }
261280 $ id = $ r ['UID ' ];
262281 $ fn = $ r ['FN ' ];
263282 $ matches [] = [
@@ -270,18 +289,15 @@ private function doSearch(string $term, array $fields, bool $strictSearch): arra
270289
271290 /**
272291 * Extracts all Contacts with the specified mail address
273- *
274- * @param string $mailAddr
275- * @return array
276292 */
277- public function getContactsWithMail (string $ mailAddr ) {
278- return $ this ->doSearch ($ mailAddr , ['EMAIL ' ], true );
293+ public function getContactsWithMail (string $ userId , string $ mailAddr ): array {
294+ return $ this ->doSearch ($ userId , $ mailAddr , ['EMAIL ' ], true );
279295 }
280296
281297 /**
282298 * Extracts all Contacts with the specified name
283299 */
284- public function getContactsWithName (string $ name ): array {
285- return $ this ->doSearch ($ name , ['FN ' ], false );
300+ public function getContactsWithName (string $ userId , string $ name ): array {
301+ return $ this ->doSearch ($ userId , $ name , ['FN ' ], false );
286302 }
287303}
0 commit comments