1 /* SOGoContactLDAPFolder.m - this file is part of SOGo
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
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)
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.
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.
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSString.h>
26 #import <Foundation/NSDictionary.h>
27 #import <Foundation/NSString.h>
29 #import <NGObjWeb/WOApplication.h>
30 #import <NGObjWeb/WOContext.h>
31 #import <NGObjWeb/WOContext+SoObjects.h>
32 #import <NGObjWeb/SoUser.h>
34 #import <NGLdap/NGLdapAttribute.h>
35 #import <NGLdap/NGLdapConnection.h>
36 #import <NGLdap/NGLdapEntry.h>
40 #import "NGLdapEntry+Contact.h"
42 #import "SOGoContactLDAPEntry.h"
43 #import "SOGoContactLDAPFolder.h"
45 #define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
49 @"sn", @"givenname", @"l", \
50 @"mail", @"telephonenumber", \
58 @implementation SOGoContactLDAPFolder
60 + (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
61 andDisplayName: (NSString *) aDisplayName
62 inContainer: (SOGoObject *) aContainer
64 SOGoContactLDAPFolder *folder;
66 folder = [[self alloc] initWithName: aName
67 andDisplayName: aDisplayName
68 inContainer: aContainer];
76 if ((self = [super init]))
79 contactIdentifier = nil;
88 - (id <SOGoContactFolder>) initWithName: (NSString *) aName
89 andDisplayName: (NSString *) aDisplayName
90 inContainer: (SOGoObject *) aContainer
92 if ((self = [self initWithName: aName
93 inContainer: aContainer]))
94 [self setDisplayName: aDisplayName];
101 [connection release];
102 [contactIdentifier release];
103 [userIdentifier release];
109 - (void) setDisplayName: (NSString *) aDisplayName
112 [displayName release];
113 displayName = aDisplayName;
115 [displayName retain];
118 - (NSString *) displayName
123 - (void) LDAPSetHostname: (NSString *) aHostname
125 setBindDN: (NSString *) aBindDN
126 setBindPW: (NSString *) aBindPW
127 setContactIdentifier: (NSString *) aCI
128 setUserIdentifier: (NSString *) aUI
129 setRootDN: (NSString *) aRootDN;
131 connection = [[NGLdapConnection alloc] initWithHostName: aHostname
133 [connection bindWithMethod: nil
135 credentials: aBindPW];
139 rootDN = [aRootDN copy];
140 if (contactIdentifier)
141 [contactIdentifier release];
142 contactIdentifier = [aCI copy];
144 [userIdentifier release];
145 userIdentifier = [aUI copy];
148 - (NGLdapConnection *) LDAPconnection
153 - (NGLdapAttribute *) _attrWithName: (NSString *) aName
155 return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
158 - (NSArray *) _searchAttributes
160 return [NSArray arrayWithObjects:
175 @"mozillaHomeCountryName",
192 @"facsimileTelephoneNumber",
194 @"mozillaHomeStreet",
195 @"mozillaSecondEmail",
196 @"xmozillasecondemail",
200 @"nscpaimscreenname",
208 @"mozillaHomePostalCode",
209 @"mozillaHomeLocalityName",
210 @"mozillaWorkStreet2",
211 @"mozillaUseHtmlMail",
212 @"xmozillausehtmlmail",
213 @"mozillaHomeStreet2",
233 - (void) _loadEntries: (NSString *) entryId
235 NSEnumerator *contacts;
240 entries = [NSMutableDictionary new];
244 if (![entries objectForKey: entryId])
247 = [connection entryAtDN:
248 [NSString stringWithFormat: @"%@=%@,%@",
249 contactIdentifier, entryId, rootDN]
250 attributes: [self _searchAttributes]];
252 [entries setObject: entry forKey: entryId];
257 contacts = [connection deepSearchAtBaseDN: rootDN
259 attributes: [self _searchAttributes]];
262 entry = [contacts nextObject];
265 key = [[entry attributeWithName: contactIdentifier]
266 stringValueAtIndex: 0];
267 if (key && ![entries objectForKey: key])
268 [entries setObject: entry forKey: key];
269 entry = [contacts nextObject];
275 - (id) lookupName: (NSString *) name
276 inContext: (WOContext *) lookupContext
277 acquire: (BOOL) acquire
282 // NSLog (@"looking up name '%@'...", name);
284 /* first check attributes directly bound to the application */
285 obj = [super lookupName: name inContext: lookupContext acquire: NO];
288 [self _loadEntries: name];
289 entry = [entries objectForKey: name];
291 ? [SOGoContactLDAPEntry contactEntryWithName: name
294 : [NSException exceptionWithHTTPStatus: 404]);
300 - (NSArray *) toOneRelationshipKeys
302 [self _loadEntries: nil];
304 return [entries allKeys];
307 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
311 [self _loadEntries: recordId];
313 entry = [entries objectForKey: recordId];
315 ? [SOGoContactLDAPEntry contactEntryWithName: recordId
321 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
324 EOQualifier *qualifier;
326 if (filter && [filter length] > 0)
328 if ([filter isEqualToString: @"."])
331 qs = [NSString stringWithFormat:
334 @"OR (displayName='%@*')"
336 @"OR (telephoneNumber='*%@*')",
337 filter, filter, filter, filter, filter];
338 qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
346 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
347 sortBy: (NSString *) sortKey
348 ordering: (NSComparisonResult) sortOrdering
350 NSMutableArray *records;
353 NSEnumerator *contacts;
354 EOSortOrdering *ordering;
358 if (filter && [filter length] > 0)
360 NSLog (@"%@: fetching records matching '%@', sorted by '%@'"
362 self, filter, sortKey, sortOrdering);
364 records = [NSMutableArray new];
365 [records autorelease];
367 contacts = [connection deepSearchAtBaseDN: rootDN
368 qualifier: [self _qualifierForFilter: filter]
369 attributes: folderListingFields];
370 entry = [contacts nextObject];
373 [records addObject: [entry asDictionaryWithAttributeNames: nil
374 withUID: userIdentifier
375 andCName: contactIdentifier]];
376 entry = [contacts nextObject];
380 = [EOSortOrdering sortOrderingWithKey: sortKey
381 selector: ((sortOrdering == NSOrderedDescending)
382 ? EOCompareCaseInsensitiveDescending
383 : EOCompareCaseInsensitiveAscending)];
385 = [records sortedArrayUsingKeyOrderArray:
386 [NSArray arrayWithObject: ordering]];
389 //[self debugWithFormat:@"fetched %i records.", [records count]];
393 - (NSString *) groupDavResourceType
395 return @"vcard-collection";
399 /* TODO: this might change one day when we support LDAP acls */
400 - (NSArray *) aclsForUser: (NSString *) uid