Monotone-Parent: 10bf3b04ce5a5a21464583f7f4e84e2f1a15ebbd
Monotone-Revision: bc323b6b1daa8bf2032ce4ebb7f5596ad96cba2f Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2006-08-09T21:22:26 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
b5aef7b657
commit
1e478b6a31
|
@ -1,5 +1,9 @@
|
|||
2006-08-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/Contacts/SOGoContactLDAPFolder.[hm]: new class that
|
||||
returns entries an LDAP server. Conforms to the new
|
||||
SOGOContactFolder protocol.
|
||||
|
||||
* SoObjects/Contacts/SOGoContactLDAPEntry.[hm]: new class that
|
||||
returns a vCard based on contact entries from an LDAP server.
|
||||
Conforms to the new SOGOContactObject protocol.
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* SOGoContactLDAPFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SOGOCONTACTLDAPFOLDER_H
|
||||
#define SOGOCONTACTLDAPFOLDER_H
|
||||
|
||||
#import <SOGo/SOGoObject.h>
|
||||
#import "SOGoContactFolder.h"
|
||||
|
||||
@class NSString, NSArray;
|
||||
@class NGLdapConnection;
|
||||
|
||||
@interface SOGoContactLDAPFolder : SOGoObject <SOGoContactFolder>
|
||||
{
|
||||
NGLdapConnection *connection;
|
||||
NSString *contactIdentifier;
|
||||
NSString *rootDN;
|
||||
NSString *displayName;
|
||||
NSMutableDictionary *entries;
|
||||
}
|
||||
|
||||
- (NGLdapConnection *) LDAPconnection;
|
||||
|
||||
- (void) setDisplayName: (NSString *) aDisplayName;
|
||||
- (NSString *) displayName;
|
||||
|
||||
- (void) LDAPSetHostname: (NSString *) aHostname
|
||||
setPort: (int) aPort
|
||||
setBindDN: (NSString *) aBindDN
|
||||
setBindPW: (NSString *) aBindPW
|
||||
setContactIdentifier: (NSString *) aCI
|
||||
setRootDN: (NSString *) aRootDN;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif /* SOGOCONTACTLDAPFOLDER_H */
|
|
@ -0,0 +1,375 @@
|
|||
/* SOGoContactLDAPFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/SoUser.h>
|
||||
|
||||
#import <NGLdap/NGLdapAttribute.h>
|
||||
#import <NGLdap/NGLdapConnection.h>
|
||||
#import <NGLdap/NGLdapEntry.h>
|
||||
|
||||
#import "common.h"
|
||||
|
||||
#import "NGLdapEntry+Contact.h"
|
||||
|
||||
#import "SOGoContactLDAPEntry.h"
|
||||
#import "SOGoContactLDAPFolder.h"
|
||||
|
||||
@class WOContext;
|
||||
|
||||
@implementation SOGoContactLDAPFolder
|
||||
|
||||
+ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (SOGoObject *) aContainer
|
||||
{
|
||||
SOGoContactLDAPFolder *folder;
|
||||
|
||||
folder = [[self alloc] initWithName: aName
|
||||
andDisplayName: aDisplayName
|
||||
inContainer: aContainer];
|
||||
[folder autorelease];
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
connection = nil;
|
||||
contactIdentifier = nil;
|
||||
rootDN = nil;
|
||||
entries = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id <SOGoContactFolder>) initWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (SOGoObject *) aContainer
|
||||
{
|
||||
if ((self = [self initWithName: aName
|
||||
inContainer: aContainer]))
|
||||
[self setDisplayName: aDisplayName];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (connection)
|
||||
{
|
||||
if ([connection isBound])
|
||||
[connection unbind];
|
||||
[connection release];
|
||||
}
|
||||
if (contactIdentifier)
|
||||
[contactIdentifier release];
|
||||
if (rootDN)
|
||||
[rootDN release];
|
||||
if (entries)
|
||||
[entries release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setDisplayName: (NSString *) aDisplayName
|
||||
{
|
||||
if (displayName)
|
||||
[displayName release];
|
||||
displayName = aDisplayName;
|
||||
if (displayName)
|
||||
[displayName retain];
|
||||
}
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
- (void) LDAPSetHostname: (NSString *) aHostname
|
||||
setPort: (int) aPort
|
||||
setBindDN: (NSString *) aBindDN
|
||||
setBindPW: (NSString *) aBindPW
|
||||
setContactIdentifier: (NSString *) aCI
|
||||
setRootDN: (NSString *) aRootDN;
|
||||
{
|
||||
connection = [[NGLdapConnection alloc] initWithHostName: aHostname
|
||||
port: aPort];
|
||||
[connection bindWithMethod: nil
|
||||
binddn: aBindDN
|
||||
credentials: aBindPW];
|
||||
|
||||
if (rootDN)
|
||||
[rootDN release];
|
||||
rootDN = [aRootDN copy];
|
||||
if (contactIdentifier)
|
||||
[contactIdentifier release];
|
||||
contactIdentifier = [aCI copy];
|
||||
}
|
||||
|
||||
- (NGLdapConnection *) LDAPconnection
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
|
||||
- (NGLdapAttribute *) _attrWithName: (NSString *) aName
|
||||
{
|
||||
return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
|
||||
}
|
||||
|
||||
- (NSArray *) _searchAttributes
|
||||
{
|
||||
return [NSArray arrayWithObjects:
|
||||
@"title",
|
||||
@"company",
|
||||
@"o",
|
||||
@"modifytimestamp",
|
||||
@"mozillaHomeState",
|
||||
@"mozillaHomeUrl",
|
||||
@"homeurl",
|
||||
@"st",
|
||||
@"region",
|
||||
@"mozillaCustom2",
|
||||
@"custom2",
|
||||
@"mozillaHomeCountryName",
|
||||
@"description",
|
||||
@"notes",
|
||||
@"department",
|
||||
@"departmentnumber",
|
||||
@"ou",
|
||||
@"orgunit",
|
||||
@"mobile",
|
||||
@"cellphone",
|
||||
@"carphone",
|
||||
@"mozillaCustom1",
|
||||
@"custom1",
|
||||
@"mozillaNickname",
|
||||
@"xmozillanickname",
|
||||
@"mozillaWorkUrl",
|
||||
@"workurl",
|
||||
@"fax",
|
||||
@"facsimileTelephoneNumber",
|
||||
@"telephoneNumber",
|
||||
@"mozillaHomeStreet",
|
||||
@"mozillaSecondEmail",
|
||||
@"xmozillasecondemail",
|
||||
@"mozillaCustom4",
|
||||
@"custom4",
|
||||
@"nsAIMid",
|
||||
@"nscpaimscreenname",
|
||||
@"street",
|
||||
@"streetaddress",
|
||||
@"postOfficeBox",
|
||||
@"homePhone",
|
||||
@"cn",
|
||||
contactIdentifier,
|
||||
@"commonname",
|
||||
@"givenName",
|
||||
@"mozillaHomePostalCode",
|
||||
@"mozillaHomeLocalityName",
|
||||
@"mozillaWorkStreet2",
|
||||
@"mozillaUseHtmlMail",
|
||||
@"xmozillausehtmlmail",
|
||||
@"mozillaHomeStreet2",
|
||||
@"postalCode",
|
||||
@"zip",
|
||||
@"c",
|
||||
@"countryname",
|
||||
@"pager",
|
||||
@"pagerphone",
|
||||
@"mail",
|
||||
@"sn",
|
||||
@"surname",
|
||||
@"mozillaCustom3",
|
||||
@"custom3",
|
||||
@"l",
|
||||
@"locality",
|
||||
@"birthyear",
|
||||
@"serialNumber",
|
||||
nil];
|
||||
}
|
||||
|
||||
- (void) _loadEntries: (NSString *) entryId
|
||||
{
|
||||
NSEnumerator *contacts;
|
||||
NGLdapEntry *entry;
|
||||
NSString *key;
|
||||
|
||||
if (!entries)
|
||||
entries = [NSMutableDictionary new];
|
||||
|
||||
if (entryId)
|
||||
{
|
||||
if (![entries objectForKey: entryId])
|
||||
{
|
||||
entry
|
||||
= [connection entryAtDN:
|
||||
[NSString stringWithFormat: @"%@=%@,%@",
|
||||
contactIdentifier, entryId, rootDN]
|
||||
attributes: [self _searchAttributes]];
|
||||
if (entry)
|
||||
[entries setObject: entry forKey: entryId];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
contacts = [connection deepSearchAtBaseDN: rootDN
|
||||
qualifier: nil
|
||||
attributes: [self _searchAttributes]];
|
||||
if (contacts)
|
||||
{
|
||||
entry = [contacts nextObject];
|
||||
while (entry)
|
||||
{
|
||||
key = [[entry attributeWithName: contactIdentifier]
|
||||
stringValueAtIndex: 0];
|
||||
if (key && ![entries objectForKey: key])
|
||||
[entries setObject: entry forKey: key];
|
||||
entry = [contacts nextObject];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (id) lookupName: (NSString *) name
|
||||
inContext: (WOContext *) context
|
||||
acquire: (BOOL) acquire
|
||||
{
|
||||
id obj;
|
||||
NGLdapEntry *entry;
|
||||
|
||||
NSLog (@"looking up name '%@'...", name);
|
||||
|
||||
/* first check attributes directly bound to the application */
|
||||
obj = [super lookupName: name inContext: context acquire: NO];
|
||||
if (!obj)
|
||||
{
|
||||
[self _loadEntries: name];
|
||||
entry = [entries objectForKey: name];
|
||||
obj = ((entry)
|
||||
? [SOGoContactLDAPEntry contactEntryWithName: name
|
||||
withLDAPEntry: entry
|
||||
inContainer: self]
|
||||
: [NSException exceptionWithHTTPStatus: 404]);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSArray *) toOneRelationshipKeys
|
||||
{
|
||||
[self _loadEntries: nil];
|
||||
|
||||
return [entries allKeys];
|
||||
}
|
||||
|
||||
- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
|
||||
{
|
||||
NGLdapEntry *entry;
|
||||
|
||||
[self _loadEntries: recordId];
|
||||
|
||||
entry = [entries objectForKey: recordId];
|
||||
return ((entry)
|
||||
? [SOGoContactLDAPEntry contactEntryWithName: recordId
|
||||
withLDAPEntry: entry
|
||||
inContainer: self]
|
||||
: nil);
|
||||
}
|
||||
|
||||
- (EOQualifier *) _qualifierForFilter: (NSString *) filter
|
||||
{
|
||||
NSString *qs;
|
||||
EOQualifier *qualifier;
|
||||
|
||||
if (filter && [filter length] > 0)
|
||||
{
|
||||
qs = [NSString stringWithFormat:
|
||||
@"(cn='*%@*')"
|
||||
@"OR (mail='*%@*')"
|
||||
@"OR (telephoneNumber='*%@*')",
|
||||
filter, filter, filter];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||
}
|
||||
else
|
||||
qualifier = nil;
|
||||
|
||||
return qualifier;
|
||||
}
|
||||
|
||||
- (NSArray *) lookupContactsWithFilter: (NSString *) filter
|
||||
sortBy: (NSString *) sortKey
|
||||
ordering: (NSComparisonResult) sortOrdering
|
||||
{
|
||||
NSMutableArray *records;
|
||||
NSArray *result;
|
||||
NGLdapEntry *entry;
|
||||
NSEnumerator *contacts;
|
||||
EOSortOrdering *ordering;
|
||||
|
||||
result = nil;
|
||||
|
||||
if (filter && [filter length] > 0)
|
||||
{
|
||||
NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
|
||||
@" in order %d",
|
||||
self, filter, sortKey, sortOrdering);
|
||||
|
||||
records = [NSMutableArray new];
|
||||
[records autorelease];
|
||||
|
||||
contacts = [connection deepSearchAtBaseDN: rootDN
|
||||
qualifier: [self _qualifierForFilter: filter]
|
||||
attributes: folderListingFields];
|
||||
entry = [contacts nextObject];
|
||||
while (entry)
|
||||
{
|
||||
[records addObject: [entry asDictionaryWithAttributeNames: nil
|
||||
andCName: @"cn"]];
|
||||
entry = [contacts nextObject];
|
||||
}
|
||||
|
||||
ordering
|
||||
= [EOSortOrdering sortOrderingWithKey: sortKey
|
||||
selector: ((sortOrdering == NSOrderedDescending)
|
||||
? EOCompareCaseInsensitiveDescending
|
||||
: EOCompareCaseInsensitiveAscending)];
|
||||
result
|
||||
= [records sortedArrayUsingKeyOrderArray:
|
||||
[NSArray arrayWithObject: ordering]];
|
||||
}
|
||||
|
||||
//[self debugWithFormat:@"fetched %i records.", [records count]];
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue