1414use OCP \IConfig ;
1515use OCP \IGroupManager ;
1616use OCP \IUserManager ;
17+ use function is_array ;
1718
1819class ContactsIntegration {
1920 /** @var IManager */
@@ -46,55 +47,9 @@ public function __construct(IManager $contactsManager,
4647 * @return array
4748 */
4849 public function getMatchingRecipient (string $ userId , string $ term ): array {
49- if (!$ this ->contactsManager ->isEnabled ()) {
50- return [];
51- }
52-
53- // If 'Allow username autocompletion in share dialog' is disabled in the admin sharing settings, then we must not
54- // auto-complete system users
55- $ shareeEnumeration = $ this ->config ->getAppValue ('core ' , 'shareapi_allow_share_dialog_user_enumeration ' , 'yes ' ) === 'yes ' ;
56- $ shareeEnumerationInGroupOnly = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_to_group ' , 'no ' ) === 'yes ' ;
57- $ shareeEnumerationFullMatch = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match ' , 'yes ' ) === 'yes ' ;
58- $ shareeEnumerationFullMatchUserId = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_userid ' , 'yes ' ) === 'yes ' ;
59- $ shareeEnumerationFullMatchEmail = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_email ' , 'yes ' ) === 'yes ' ;
60-
61- $ result = $ this ->contactsManager ->search (
62- $ term ,
63- ['UID ' , 'FN ' , 'EMAIL ' ],
64- [
65- 'enumeration ' => $ shareeEnumeration ,
66- 'fullmatch ' => $ shareeEnumerationFullMatch ,
67- 'limit ' => 20 ,
68- ],
69- );
70- if (empty ($ result )) {
71- return [];
72- }
50+ $ result = $ this ->search ($ userId , $ term , ['UID ' , 'FN ' , 'EMAIL ' ]);
7351 $ receivers = [];
74-
75- if ($ shareeEnumeration && $ shareeEnumerationInGroupOnly ) {
76- $ user = $ this ->userManager ->get ($ userId );
77- if ($ user === null ) {
78- return [];
79- }
80- $ userGroups = $ this ->groupManager ->getUserGroupIds ($ user );
81- }
82-
8352 foreach ($ result as $ r ) {
84- $ isSystemUser = isset ($ r ['isLocalSystemBook ' ]) && $ r ['isLocalSystemBook ' ];
85- $ isInSameGroup = false ;
86- if ($ isSystemUser && $ shareeEnumerationInGroupOnly ) {
87- foreach ($ userGroups as $ userGroup ) {
88- if ($ this ->groupManager ->isInGroup ($ r ['UID ' ], $ userGroup )) {
89- $ isInSameGroup = true ;
90- break ;
91- }
92- }
93- if (!$ shareeEnumerationFullMatch && !$ isInSameGroup ) {
94- continue ;
95- }
96- }
97-
9853 $ id = $ r ['UID ' ];
9954 $ fn = $ r ['FN ' ] ?? null ;
10055 if (!isset ($ r ['EMAIL ' ])) {
@@ -111,23 +66,10 @@ public function getMatchingRecipient(string $userId, string $term): array {
11166 if ($ e === '' ) {
11267 continue ;
11368 }
114- $ lowerTerm = strtolower ($ term );
115-
116- if ($ isSystemUser && $ shareeEnumerationInGroupOnly && !$ isInSameGroup ) {
117- // Check for full match. If full match is disabled, matching results already filtered out
118- if (!($ lowerTerm !== '' && (
119- ($ shareeEnumerationFullMatch && !empty ($ fn ) && $ lowerTerm === strtolower ($ fn ))
120- || ($ shareeEnumerationFullMatchUserId && $ lowerTerm === strtolower ($ id ))
121- || ($ shareeEnumerationFullMatchEmail && $ lowerTerm === strtolower ($ e ))))) {
122- // Not a full Match
123- continue ;
124- }
125- }
126-
12769 $ receivers [] = [
12870 'id ' => $ id ,
12971 // Show full name if possible or fall back to email
130- 'label ' => $ fn ,
72+ 'label ' => $ fn ?? $ e ,
13173 'email ' => $ e ,
13274 'photo ' => $ photo ,
13375 'source ' => 'contacts ' ,
@@ -229,21 +171,98 @@ public function newContact(string $name, string $mailAddr, string $type = 'HOME'
229171 return $ createdContact ;
230172 }
231173
174+ private function search (string $ userId , string $ term , array $ fields , ?bool $ strictSearch = null ): array {
175+ if (!$ this ->contactsManager ->isEnabled ()) {
176+ return [];
177+ }
178+
179+ // If 'Allow username autocompletion in share dialog' is disabled in the admin sharing settings, then we must not
180+ // auto-complete system users
181+ $ shareeEnumeration = $ this ->config ->getAppValue ('core ' , 'shareapi_allow_share_dialog_user_enumeration ' , 'yes ' ) === 'yes ' ;
182+ $ shareeEnumerationInGroupOnly = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_to_group ' , 'no ' ) === 'yes ' ;
183+ $ shareeEnumerationFullMatch = $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match ' , 'yes ' ) === 'yes ' ;
184+ $ shareeEnumerationFullMatchDisplayName = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_displayname ' , 'yes ' ) === 'yes ' ;
185+ $ shareeEnumerationFullMatchUserId = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_userid ' , 'yes ' ) === 'yes ' ;
186+ $ shareeEnumerationFullMatchEmail = $ shareeEnumerationFullMatch && $ this ->config ->getAppValue ('core ' , 'shareapi_restrict_user_enumeration_full_match_email ' , 'yes ' ) === 'yes ' ;
187+
188+ $ options = [
189+ 'enumeration ' => $ shareeEnumeration ,
190+ 'fullmatch ' => $ shareeEnumerationFullMatch ,
191+ 'limit ' => 20 ,
192+ ];
193+ if ($ strictSearch !== null ) {
194+ $ options ['strict_search ' ] = $ strictSearch ;
195+ }
196+
197+ $ result = $ this ->contactsManager ->search (
198+ $ term ,
199+ $ fields ,
200+ $ options ,
201+ );
202+
203+ $ userGroups = [];
204+ if ($ shareeEnumeration && $ shareeEnumerationInGroupOnly ) {
205+ $ user = $ this ->userManager ->get ($ userId );
206+ if ($ user === null ) {
207+ return [];
208+ }
209+ $ userGroups = $ this ->groupManager ->getUserGroupIds ($ user );
210+ }
211+
212+ $ filteredResults = [];
213+ foreach ($ result as $ r ) {
214+ $ isSystemUser = isset ($ r ['isLocalSystemBook ' ]) && $ r ['isLocalSystemBook ' ];
215+ $ isInSameGroup = false ;
216+ if ($ isSystemUser && $ shareeEnumerationInGroupOnly ) {
217+ foreach ($ userGroups as $ userGroup ) {
218+ if ($ this ->groupManager ->isInGroup ($ r ['UID ' ], $ userGroup )) {
219+ $ isInSameGroup = true ;
220+ break ;
221+ }
222+ }
223+ if (!$ shareeEnumerationFullMatch && !$ isInSameGroup ) {
224+ continue ;
225+ }
226+ }
227+
228+ if ($ isSystemUser && $ shareeEnumerationInGroupOnly && !$ isInSameGroup && $ shareeEnumerationFullMatch ) {
229+ // Check for full match. If full match is disabled, non-matching results already filtered out above.
230+ $ id = $ r ['UID ' ];
231+ $ fn = $ r ['FN ' ] ?? null ;
232+ $ lowerTerm = strtolower ($ term );
233+ $ isMatch = ($ lowerTerm !== '' && (
234+ ($ shareeEnumerationFullMatchDisplayName && !empty ($ fn ) && $ lowerTerm === strtolower ($ fn ))
235+ || ($ shareeEnumerationFullMatchUserId && $ lowerTerm === strtolower ($ id )))) ;
236+ if ($ shareeEnumerationFullMatchEmail && !$ isMatch ) {
237+ $ email = $ r ['EMAIL ' ] ?? null ;
238+ if ($ email === null ) {
239+ continue ;
240+ }
241+ $ emails = is_array ($ email ) ? $ email : [$ email ];
242+ foreach ($ emails as $ e ) {
243+ if ($ lowerTerm === strtolower ($ e )) {
244+ $ isMatch = true ;
245+ break ;
246+ }
247+ }
248+ }
249+ if (!$ isMatch ) {
250+ continue ;
251+ }
252+ }
253+
254+ $ filteredResults [] = $ r ;
255+ }
256+ return $ filteredResults ;
257+ }
258+
232259 /**
233260 * @param string[] $fields
234261 */
235- private function doSearch (string $ term , array $ fields , bool $ strictSearch ) : array {
236- $ allowSystemUsers = $ this ->config ->getAppValue ('core ' , 'shareapi_allow_share_dialog_user_enumeration ' , 'yes ' ) === 'yes ' ;
237-
238- $ result = $ this ->contactsManager ->search ($ term , $ fields , [
239- 'strict_search ' => $ strictSearch ,
240- 'limit ' => 20 ,
241- ]);
262+ private function doSearch (string $ userId , string $ term , array $ fields , bool $ strictSearch ) : array {
263+ $ result = $ this ->search ($ userId , $ term , $ fields , $ strictSearch );
242264 $ matches = [];
243265 foreach ($ result as $ r ) {
244- if (!$ allowSystemUsers && isset ($ r ['isLocalSystemBook ' ]) && $ r ['isLocalSystemBook ' ]) {
245- continue ;
246- }
247266 $ id = $ r ['UID ' ];
248267 $ fn = $ r ['FN ' ];
249268 $ email = $ r ['EMAIL ' ] ?? null ;
@@ -258,18 +277,15 @@ private function doSearch(string $term, array $fields, bool $strictSearch) : arr
258277
259278 /**
260279 * Extracts all Contacts with the specified mail address
261- *
262- * @param string $mailAddr
263- * @return array
264280 */
265- public function getContactsWithMail (string $ mailAddr ) {
266- return $ this ->doSearch ($ mailAddr , ['EMAIL ' ], true );
281+ public function getContactsWithMail (string $ userId , string $ mailAddr ): array {
282+ return $ this ->doSearch ($ userId , $ mailAddr , ['EMAIL ' ], true );
267283 }
268284
269285 /**
270286 * Extracts all Contacts with the specified name
271287 */
272- public function getContactsWithName (string $ name ): array {
273- return $ this ->doSearch ($ name , ['FN ' ], false );
288+ public function getContactsWithName (string $ userId , string $ name ): array {
289+ return $ this ->doSearch ($ userId , $ name , ['FN ' ], false );
274290 }
275291}
0 commit comments