]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Contacts/SOGoContactLDAPFolder.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1033 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / Contacts / SOGoContactLDAPFolder.m
1 /* SOGoContactLDAPFolder.m - this file is part of SOGo
2  *
3  * Copyright (C) 2006 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSString.h>
25
26 #import <Foundation/NSDictionary.h>
27 #import <Foundation/NSString.h>
28
29 #import <NGObjWeb/WOApplication.h>
30 #import <NGObjWeb/WOContext.h>
31 #import <NGObjWeb/WOContext+SoObjects.h>
32 #import <NGObjWeb/SoUser.h>
33
34 #import <NGLdap/NGLdapAttribute.h>
35 #import <NGLdap/NGLdapConnection.h>
36 #import <NGLdap/NGLdapEntry.h>
37
38 #import "common.h"
39
40 #import "NGLdapEntry+Contact.h"
41
42 #import "SOGoContactLDAPEntry.h"
43 #import "SOGoContactLDAPFolder.h"
44
45 #define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
46                                      @"displayName",                     \
47                                      @"streetAddress",                   \
48                                      @"sn", @"givenname", @"l",          \
49                                      @"mail", @"telephonenumber",        \
50                                      @"mailNickname",                    \
51                                      @"sAMAccountName",                  \
52                                      nil]
53
54 @class WOContext;
55
56 @implementation SOGoContactLDAPFolder
57
58 + (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
59                                   andDisplayName: (NSString *) aDisplayName
60                                      inContainer: (SOGoObject *) aContainer
61 {
62   SOGoContactLDAPFolder *folder;
63
64   folder = [[self alloc] initWithName: aName
65                          andDisplayName: aDisplayName
66                          inContainer: aContainer];
67   [folder autorelease];
68
69   return folder;
70 }
71
72 - (id) init
73 {
74   if ((self = [super init]))
75     {
76       connection = nil;
77       contactIdentifier = nil;
78       userIdentifier = nil;
79       rootDN = nil;
80       entries = nil;
81     }
82
83   return self;
84 }
85
86 - (id <SOGoContactFolder>) initWithName: (NSString *) aName
87                          andDisplayName: (NSString *) aDisplayName
88                             inContainer: (SOGoObject *) aContainer
89 {
90   if ((self = [self initWithName: aName
91                     inContainer: aContainer]))
92     [self setDisplayName: aDisplayName];
93   
94   return self;
95 }
96
97 - (void) dealloc
98 {
99   if (connection)
100     {
101       if ([connection isBound])
102         [connection unbind];
103       [connection release];
104     }
105   if (contactIdentifier)
106     [contactIdentifier release];
107   if (userIdentifier)
108     [userIdentifier release];
109   if (rootDN)
110     [rootDN release];
111   if (entries)
112     [entries release];
113   [super dealloc];
114 }
115
116 - (void) setDisplayName: (NSString *) aDisplayName
117 {
118   if (displayName)
119     [displayName release];
120   displayName = aDisplayName;
121   if (displayName)
122     [displayName retain];
123 }
124
125 - (NSString *) displayName
126 {
127   return displayName;
128 }
129
130 - (void) LDAPSetHostname: (NSString *) aHostname
131                  setPort: (int) aPort
132                setBindDN: (NSString *) aBindDN
133                setBindPW: (NSString *) aBindPW
134     setContactIdentifier: (NSString *) aCI
135        setUserIdentifier: (NSString *) aUI
136                setRootDN: (NSString *) aRootDN;
137 {
138   connection = [[NGLdapConnection alloc] initWithHostName: aHostname
139                                          port: aPort];
140   [connection bindWithMethod: nil
141               binddn: aBindDN
142               credentials: aBindPW];
143
144   if (rootDN)
145     [rootDN release];
146   rootDN = [aRootDN copy];
147   if (contactIdentifier)
148     [contactIdentifier release];
149   contactIdentifier = [aCI copy];
150   if (userIdentifier)
151     [userIdentifier release];
152   userIdentifier = [aUI copy];
153 }
154
155 - (NGLdapConnection *) LDAPconnection
156 {
157   return connection;
158 }
159
160 - (NGLdapAttribute *) _attrWithName: (NSString *) aName
161 {
162   return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
163 }
164
165 - (NSArray *) _searchAttributes
166 {
167   return [NSArray arrayWithObjects:
168                     contactIdentifier,
169                   userIdentifier,
170                   @"title",
171                   @"company",
172                   @"o",
173                   @"displayName",
174                   @"modifytimestamp",
175                   @"mozillaHomeState",
176                   @"mozillaHomeUrl",
177                   @"homeurl",
178                   @"st",
179                   @"region",
180                   @"mozillaCustom2",
181                   @"custom2",
182                   @"mozillaHomeCountryName",
183                   @"description",
184                   @"notes",
185                   @"department",
186                   @"departmentnumber",
187                   @"ou",
188                   @"orgunit",
189                   @"mobile",
190                   @"cellphone",
191                   @"carphone",
192                   @"mozillaCustom1",
193                   @"custom1",
194                   @"mozillaNickname",
195                   @"xmozillanickname",
196                   @"mozillaWorkUrl",
197                   @"workurl",
198                   @"fax",
199                   @"facsimileTelephoneNumber",
200                   @"telephoneNumber",
201                   @"mozillaHomeStreet",
202                   @"mozillaSecondEmail",
203                   @"xmozillasecondemail",
204                   @"mozillaCustom4",
205                   @"custom4",
206                   @"nsAIMid",
207                   @"nscpaimscreenname",
208                   @"street",
209                   @"streetAddress",
210                   @"postOfficeBox",
211                   @"homePhone",
212                   @"cn",
213                   @"commonname",
214                   @"givenName",
215                   @"mozillaHomePostalCode",
216                   @"mozillaHomeLocalityName",
217                   @"mozillaWorkStreet2",
218                   @"mozillaUseHtmlMail",
219                   @"xmozillausehtmlmail",
220                   @"mozillaHomeStreet2",
221                   @"postalCode",
222                   @"zip",
223                   @"c",
224                   @"countryname",
225                   @"pager",
226                   @"pagerphone",
227                   @"mail",
228                   @"sn",
229                   @"surname",
230                   @"mozillaCustom3",
231                   @"custom3",
232                   @"l",
233                   @"locality",
234                   @"birthyear",
235                   @"serialNumber",
236                   @"calFBURL",
237                   nil];
238 }
239
240 - (void) _loadEntries: (NSString *) entryId
241 {
242   NSEnumerator *contacts;
243   NGLdapEntry *entry;
244   NSString *key;
245
246   if (!entries)
247     entries = [NSMutableDictionary new];
248
249   if (entryId)
250     {
251       if (![entries objectForKey: entryId])
252         {
253           entry
254             = [connection entryAtDN:
255                             [NSString stringWithFormat: @"%@=%@,%@",
256                                       contactIdentifier, entryId, rootDN]
257                           attributes: [self _searchAttributes]];
258           if (entry)
259             [entries setObject: entry forKey: entryId];
260         }
261     }
262   else
263     {
264       contacts = [connection deepSearchAtBaseDN: rootDN
265                              qualifier: nil
266                              attributes: [self _searchAttributes]];
267       if (contacts)
268         {
269           entry = [contacts nextObject];
270           while (entry)
271             {
272               key = [[entry attributeWithName: contactIdentifier]
273                       stringValueAtIndex: 0];
274               if (key && ![entries objectForKey: key])
275                 [entries setObject: entry forKey: key];
276               entry = [contacts nextObject];
277             }
278         }
279     }
280 }
281
282 - (id) lookupName: (NSString *) name
283         inContext: (WOContext *) context
284           acquire: (BOOL) acquire
285 {
286   id obj;
287   NGLdapEntry *entry;
288
289 //   NSLog (@"looking up name '%@'...", name);
290
291   /* first check attributes directly bound to the application */
292   obj = [super lookupName: name inContext: context acquire: NO];
293   if (!obj)
294     {
295       [self _loadEntries: name];
296       entry = [entries objectForKey: name];
297       obj = ((entry)
298              ? [SOGoContactLDAPEntry contactEntryWithName: name
299                                      withLDAPEntry: entry
300                                      inContainer: self]
301              : [NSException exceptionWithHTTPStatus: 404]);
302     }
303
304   return obj;
305 }
306
307 - (NSArray *) toOneRelationshipKeys
308 {
309   [self _loadEntries: nil];
310
311   return [entries allKeys];
312 }
313
314 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
315 {
316   NGLdapEntry *entry;
317
318   [self _loadEntries: recordId];
319
320   entry = [entries objectForKey: recordId];
321   return ((entry)
322           ? [SOGoContactLDAPEntry contactEntryWithName: recordId
323                                   withLDAPEntry: entry
324                                   inContainer: self]
325           : nil);
326 }
327
328 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
329 {
330   NSString *qs;
331   EOQualifier *qualifier;
332
333   if (filter && [filter length] > 0)
334     {
335       qs = [NSString stringWithFormat:
336                        @"(cn='%@*')"
337                      @"OR (sn='%@*')"
338                      @"OR (displayName='%@*')"
339                      @"OR (mail='%@*')"
340                      @"OR (telephoneNumber='*%@*')",
341                      filter, filter, filter, filter, filter];
342       qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
343     }
344   else
345     qualifier = nil;
346
347   return qualifier;
348 }
349
350 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
351                                 sortBy: (NSString *) sortKey
352                               ordering: (NSComparisonResult) sortOrdering
353 {
354   NSMutableArray *records;
355   NSArray *result;
356   NGLdapEntry *entry;
357   NSEnumerator *contacts;
358   EOSortOrdering *ordering;
359
360   result = nil;
361
362   if (filter && [filter length] > 0)
363     {
364 //       NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
365 //              @" in order %d",
366 //              self, filter, sortKey, sortOrdering);
367
368       records = [NSMutableArray new];
369       [records autorelease];
370
371       contacts = [connection deepSearchAtBaseDN: rootDN
372                              qualifier: [self _qualifierForFilter: filter]
373                              attributes: folderListingFields];
374       entry = [contacts nextObject];
375       while (entry)
376         {
377           [records addObject: [entry asDictionaryWithAttributeNames: nil
378                                      withUID: userIdentifier
379                                      andCName: contactIdentifier]];
380           entry = [contacts nextObject];
381         }
382
383       ordering
384         = [EOSortOrdering sortOrderingWithKey: sortKey
385                           selector: ((sortOrdering == NSOrderedDescending)
386                                      ? EOCompareCaseInsensitiveDescending
387                                      : EOCompareCaseInsensitiveAscending)];
388       result
389         = [records sortedArrayUsingKeyOrderArray:
390                      [NSArray arrayWithObject: ordering]];
391     }
392
393   //[self debugWithFormat:@"fetched %i records.", [records count]];
394   return result;
395 }
396
397 - (NSString *) groupDavResourceType
398 {
399   return @"vcard-collection";
400 }
401
402 @end