]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Contacts/SOGoContactLDAPFolder.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1045 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                                      @"o", \
49                                      @"sn", @"givenname", @"l",          \
50                                      @"mail", @"telephonenumber",        \
51                                      @"mailNickname",                    \
52                                      @"sAMAccountName",                  \
53                                      nil]
54
55 @class WOContext;
56
57 @implementation SOGoContactLDAPFolder
58
59 + (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
60                                   andDisplayName: (NSString *) aDisplayName
61                                      inContainer: (SOGoObject *) aContainer
62 {
63   SOGoContactLDAPFolder *folder;
64
65   folder = [[self alloc] initWithName: aName
66                          andDisplayName: aDisplayName
67                          inContainer: aContainer];
68   [folder autorelease];
69
70   return folder;
71 }
72
73 - (id) init
74 {
75   if ((self = [super init]))
76     {
77       connection = nil;
78       contactIdentifier = nil;
79       userIdentifier = nil;
80       rootDN = nil;
81       entries = nil;
82     }
83
84   return self;
85 }
86
87 - (id <SOGoContactFolder>) initWithName: (NSString *) aName
88                          andDisplayName: (NSString *) aDisplayName
89                             inContainer: (SOGoObject *) aContainer
90 {
91   if ((self = [self initWithName: aName
92                     inContainer: aContainer]))
93     [self setDisplayName: aDisplayName];
94   
95   return self;
96 }
97
98 - (void) dealloc
99 {
100   if (connection)
101     {
102       if ([connection isBound])
103         [connection unbind];
104       [connection release];
105     }
106   if (contactIdentifier)
107     [contactIdentifier release];
108   if (userIdentifier)
109     [userIdentifier release];
110   if (rootDN)
111     [rootDN release];
112   if (entries)
113     [entries release];
114   [super dealloc];
115 }
116
117 - (void) setDisplayName: (NSString *) aDisplayName
118 {
119   if (displayName)
120     [displayName release];
121   displayName = aDisplayName;
122   if (displayName)
123     [displayName retain];
124 }
125
126 - (NSString *) displayName
127 {
128   return displayName;
129 }
130
131 - (void) LDAPSetHostname: (NSString *) aHostname
132                  setPort: (int) aPort
133                setBindDN: (NSString *) aBindDN
134                setBindPW: (NSString *) aBindPW
135     setContactIdentifier: (NSString *) aCI
136        setUserIdentifier: (NSString *) aUI
137                setRootDN: (NSString *) aRootDN;
138 {
139   connection = [[NGLdapConnection alloc] initWithHostName: aHostname
140                                          port: aPort];
141   [connection bindWithMethod: nil
142               binddn: aBindDN
143               credentials: aBindPW];
144
145   if (rootDN)
146     [rootDN release];
147   rootDN = [aRootDN copy];
148   if (contactIdentifier)
149     [contactIdentifier release];
150   contactIdentifier = [aCI copy];
151   if (userIdentifier)
152     [userIdentifier release];
153   userIdentifier = [aUI copy];
154 }
155
156 - (NGLdapConnection *) LDAPconnection
157 {
158   return connection;
159 }
160
161 - (NGLdapAttribute *) _attrWithName: (NSString *) aName
162 {
163   return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
164 }
165
166 - (NSArray *) _searchAttributes
167 {
168   return [NSArray arrayWithObjects:
169                     contactIdentifier,
170                   userIdentifier,
171                   @"title",
172                   @"company",
173                   @"o",
174                   @"displayName",
175                   @"modifytimestamp",
176                   @"mozillaHomeState",
177                   @"mozillaHomeUrl",
178                   @"homeurl",
179                   @"st",
180                   @"region",
181                   @"mozillaCustom2",
182                   @"custom2",
183                   @"mozillaHomeCountryName",
184                   @"description",
185                   @"notes",
186                   @"department",
187                   @"departmentnumber",
188                   @"ou",
189                   @"orgunit",
190                   @"mobile",
191                   @"cellphone",
192                   @"carphone",
193                   @"mozillaCustom1",
194                   @"custom1",
195                   @"mozillaNickname",
196                   @"xmozillanickname",
197                   @"mozillaWorkUrl",
198                   @"workurl",
199                   @"fax",
200                   @"facsimileTelephoneNumber",
201                   @"telephoneNumber",
202                   @"mozillaHomeStreet",
203                   @"mozillaSecondEmail",
204                   @"xmozillasecondemail",
205                   @"mozillaCustom4",
206                   @"custom4",
207                   @"nsAIMid",
208                   @"nscpaimscreenname",
209                   @"street",
210                   @"streetAddress",
211                   @"postOfficeBox",
212                   @"homePhone",
213                   @"cn",
214                   @"commonname",
215                   @"givenName",
216                   @"mozillaHomePostalCode",
217                   @"mozillaHomeLocalityName",
218                   @"mozillaWorkStreet2",
219                   @"mozillaUseHtmlMail",
220                   @"xmozillausehtmlmail",
221                   @"mozillaHomeStreet2",
222                   @"postalCode",
223                   @"zip",
224                   @"c",
225                   @"countryname",
226                   @"pager",
227                   @"pagerphone",
228                   @"mail",
229                   @"sn",
230                   @"surname",
231                   @"mozillaCustom3",
232                   @"custom3",
233                   @"l",
234                   @"locality",
235                   @"birthyear",
236                   @"serialNumber",
237                   @"calFBURL",
238                   nil];
239 }
240
241 - (void) _loadEntries: (NSString *) entryId
242 {
243   NSEnumerator *contacts;
244   NGLdapEntry *entry;
245   NSString *key;
246
247   if (!entries)
248     entries = [NSMutableDictionary new];
249
250   if (entryId)
251     {
252       if (![entries objectForKey: entryId])
253         {
254           entry
255             = [connection entryAtDN:
256                             [NSString stringWithFormat: @"%@=%@,%@",
257                                       contactIdentifier, entryId, rootDN]
258                           attributes: [self _searchAttributes]];
259           if (entry)
260             [entries setObject: entry forKey: entryId];
261         }
262     }
263   else
264     {
265       contacts = [connection deepSearchAtBaseDN: rootDN
266                              qualifier: nil
267                              attributes: [self _searchAttributes]];
268       if (contacts)
269         {
270           entry = [contacts nextObject];
271           while (entry)
272             {
273               key = [[entry attributeWithName: contactIdentifier]
274                       stringValueAtIndex: 0];
275               if (key && ![entries objectForKey: key])
276                 [entries setObject: entry forKey: key];
277               entry = [contacts nextObject];
278             }
279         }
280     }
281 }
282
283 - (id) lookupName: (NSString *) name
284         inContext: (WOContext *) lookupContext
285           acquire: (BOOL) acquire
286 {
287   id obj;
288   NGLdapEntry *entry;
289
290 //   NSLog (@"looking up name '%@'...", name);
291
292   /* first check attributes directly bound to the application */
293   obj = [super lookupName: name inContext: lookupContext acquire: NO];
294   if (!obj)
295     {
296       [self _loadEntries: name];
297       entry = [entries objectForKey: name];
298       obj = ((entry)
299              ? [SOGoContactLDAPEntry contactEntryWithName: name
300                                      withLDAPEntry: entry
301                                      inContainer: self]
302              : [NSException exceptionWithHTTPStatus: 404]);
303     }
304
305   return obj;
306 }
307
308 - (NSArray *) toOneRelationshipKeys
309 {
310   [self _loadEntries: nil];
311
312   return [entries allKeys];
313 }
314
315 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
316 {
317   NGLdapEntry *entry;
318
319   [self _loadEntries: recordId];
320
321   entry = [entries objectForKey: recordId];
322   return ((entry)
323           ? [SOGoContactLDAPEntry contactEntryWithName: recordId
324                                   withLDAPEntry: entry
325                                   inContainer: self]
326           : nil);
327 }
328
329 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
330 {
331   NSString *qs;
332   EOQualifier *qualifier;
333
334   if (filter && [filter length] > 0)
335     {
336       qs = [NSString stringWithFormat:
337                        @"(cn='%@*')"
338                      @"OR (sn='%@*')"
339                      @"OR (displayName='%@*')"
340                      @"OR (mail='%@*')"
341                      @"OR (telephoneNumber='*%@*')",
342                      filter, filter, filter, filter, filter];
343       qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
344     }
345   else
346     qualifier = nil;
347
348   return qualifier;
349 }
350
351 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
352                                 sortBy: (NSString *) sortKey
353                               ordering: (NSComparisonResult) sortOrdering
354 {
355   NSMutableArray *records;
356   NSArray *result;
357   NGLdapEntry *entry;
358   NSEnumerator *contacts;
359   EOSortOrdering *ordering;
360
361   result = nil;
362
363   if (filter && [filter length] > 0)
364     {
365 //       NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
366 //              @" in order %d",
367 //              self, filter, sortKey, sortOrdering);
368
369       records = [NSMutableArray new];
370       [records autorelease];
371
372       contacts = [connection deepSearchAtBaseDN: rootDN
373                              qualifier: [self _qualifierForFilter: filter]
374                              attributes: folderListingFields];
375       entry = [contacts nextObject];
376       while (entry)
377         {
378           [records addObject: [entry asDictionaryWithAttributeNames: nil
379                                      withUID: userIdentifier
380                                      andCName: contactIdentifier]];
381           entry = [contacts nextObject];
382         }
383
384       ordering
385         = [EOSortOrdering sortOrderingWithKey: sortKey
386                           selector: ((sortOrdering == NSOrderedDescending)
387                                      ? EOCompareCaseInsensitiveDescending
388                                      : EOCompareCaseInsensitiveAscending)];
389       result
390         = [records sortedArrayUsingKeyOrderArray:
391                      [NSArray arrayWithObject: ordering]];
392     }
393
394   //[self debugWithFormat:@"fetched %i records.", [records count]];
395   return result;
396 }
397
398 - (NSString *) groupDavResourceType
399 {
400   return @"vcard-collection";
401 }
402
403 @end