Applied last changed from ca.inverse.sogo branch, pertaining to iOS handling of CardDAV
Monotone-Parent: bee9d78831eda60f6cda2aadb62fc4a04a2e8e10 Monotone-Revision: 693036245b42a3d0059f8c06a2a725e716d54c9e Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-30T14:07:36
This commit is contained in:
parent
0c2c418046
commit
f06d57373a
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
||||||
|
2012-03-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/Contacts/SOGoFolder+CardDAV.m (_isValidFilter:):
|
||||||
|
accept "email" as filter name.
|
||||||
|
(_appendObject:withBaseURL:toREPORTResponse:): fixed the ordering
|
||||||
|
of XML elements as the address*-data props where put outside of
|
||||||
|
the <D:prop> tree.
|
||||||
|
|
||||||
|
* SoObjects/SOGo/LDAPSource.m (-allEntryIDs): take the _filter
|
||||||
|
ivar into account.
|
||||||
|
|
||||||
|
2012-03-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/Contacts/SOGoContactFolders.m
|
||||||
|
(-lookupName:inContext:acquire:): overriden method that enables
|
||||||
|
the lookup of hidden public sources with iOS devices.
|
||||||
|
|
||||||
|
* SoObjects/Contacts/SOGoContactLDIFEntry.m (-davAddressData): new
|
||||||
|
getter similar to davCalendarData.
|
||||||
|
|
||||||
|
* SoObjects/Contacts/SOGoContactSourceFolder.m
|
||||||
|
(-davAddressbookMultiget): new REPORT handler based on
|
||||||
|
-[SOGoAppointmentFolder davCalendarMultiget].
|
||||||
|
|
||||||
|
* SoObjects/Contacts/SOGoUserFolder+Contacts.m
|
||||||
|
(-davDirectoryGateway): new getter that returns the url to the
|
||||||
|
first available directory source.
|
||||||
|
(-davResourceType): declare resource as "directory" (carddav).
|
||||||
|
|
||||||
2012-03-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2012-03-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
* OpenChange/MAPIStoreTasksMessage.m (-save): take PR_HTML as
|
* OpenChange/MAPIStoreTasksMessage.m (-save): take PR_HTML as
|
||||||
|
|
|
@ -259,6 +259,52 @@
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id) lookupName: (NSString *) name
|
||||||
|
inContext: (WOContext *) lookupContext
|
||||||
|
acquire: (BOOL) acquire
|
||||||
|
{
|
||||||
|
id folder = nil;
|
||||||
|
SOGoUser *currentUser;
|
||||||
|
SOGoUserManager *um;
|
||||||
|
SOGoSystemDefaults *sd;
|
||||||
|
NSEnumerator *domains;
|
||||||
|
NSArray *sourceIDs;
|
||||||
|
NSString *domain, *srcDisplayName;
|
||||||
|
|
||||||
|
if ([[context request] isIPhoneAddressBookApp])
|
||||||
|
{
|
||||||
|
currentUser = [context activeUser];
|
||||||
|
if (activeUserIsOwner
|
||||||
|
|| [[currentUser login] isEqualToString: owner])
|
||||||
|
{
|
||||||
|
domain = [currentUser domain];
|
||||||
|
um = [SOGoUserManager sharedUserManager];
|
||||||
|
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||||
|
domains = [[sd visibleDomainsForDomain: domain] objectEnumerator];
|
||||||
|
while (domain)
|
||||||
|
{
|
||||||
|
sourceIDs = [um addressBookSourceIDsInDomain: domain];
|
||||||
|
if ([sourceIDs containsObject: name])
|
||||||
|
{
|
||||||
|
srcDisplayName = [um displayNameForSourceWithID: name];
|
||||||
|
folder = [SOGoContactSourceFolder
|
||||||
|
folderWithName: name
|
||||||
|
andDisplayName: srcDisplayName
|
||||||
|
inContainer: self];
|
||||||
|
[folder setSource: [um sourceWithID: name]];
|
||||||
|
}
|
||||||
|
domain = [domains nextObject];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!folder)
|
||||||
|
folder = [super lookupName: name inContext: lookupContext
|
||||||
|
acquire: acquire];
|
||||||
|
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSException *) setDavContactsCategories: (NSString *) newCategories
|
- (NSException *) setDavContactsCategories: (NSString *) newCategories
|
||||||
{
|
{
|
||||||
SOGoUser *ownerUser;
|
SOGoUser *ownerUser;
|
||||||
|
|
|
@ -166,6 +166,11 @@
|
||||||
return @"text/x-vcard";
|
return @"text/x-vcard";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *) davAddressData
|
||||||
|
{
|
||||||
|
return [self contentAsString];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSException *) save
|
- (NSException *) save
|
||||||
{
|
{
|
||||||
return [(SOGoContactSourceFolder *) container saveLDIFEntry: self];
|
return [(SOGoContactSourceFolder *) container saveLDIFEntry: self];
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSEnumerator.h>
|
#import <Foundation/NSEnumerator.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSURL.h>
|
||||||
#import <Foundation/NSValue.h>
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
#import <NGObjWeb/NSException+HTTP.h>
|
#import <NGObjWeb/NSException+HTTP.h>
|
||||||
|
@ -34,17 +35,23 @@
|
||||||
#import <NGObjWeb/SoObject.h>
|
#import <NGObjWeb/SoObject.h>
|
||||||
#import <NGObjWeb/SoSelectorInvocation.h>
|
#import <NGObjWeb/SoSelectorInvocation.h>
|
||||||
#import <NGObjWeb/SoUser.h>
|
#import <NGObjWeb/SoUser.h>
|
||||||
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
#import <NGExtensions/NSString+misc.h>
|
#import <NGExtensions/NSString+misc.h>
|
||||||
|
#import <DOM/DOMElement.h>
|
||||||
|
#import <DOM/DOMProtocols.h>
|
||||||
#import <EOControl/EOSortOrdering.h>
|
#import <EOControl/EOSortOrdering.h>
|
||||||
#import <SaxObjC/XMLNamespaces.h>
|
#import <SaxObjC/XMLNamespaces.h>
|
||||||
|
|
||||||
|
#import <SOGo/DOMNode+SOGo.h>
|
||||||
#import <SOGo/NSArray+Utilities.h>
|
#import <SOGo/NSArray+Utilities.h>
|
||||||
#import <SOGo/NSDictionary+Utilities.h>
|
#import <SOGo/NSDictionary+Utilities.h>
|
||||||
#import <SOGo/NSString+Utilities.h>
|
#import <SOGo/NSString+Utilities.h>
|
||||||
|
#import <SOGo/NSObject+DAV.h>
|
||||||
#import <SOGo/SOGoPermissions.h>
|
#import <SOGo/SOGoPermissions.h>
|
||||||
#import <SOGo/SOGoSource.h>
|
#import <SOGo/SOGoSource.h>
|
||||||
#import <SOGo/SOGoUserSettings.h>
|
#import <SOGo/SOGoUserSettings.h>
|
||||||
#import <SOGo/WORequest+SOGo.h>
|
#import <SOGo/WORequest+SOGo.h>
|
||||||
|
#import <SOGo/WOResponse+SOGo.h>
|
||||||
|
|
||||||
#import "SOGoContactFolders.h"
|
#import "SOGoContactFolders.h"
|
||||||
#import "SOGoContactGCSFolder.h"
|
#import "SOGoContactGCSFolder.h"
|
||||||
|
@ -130,14 +137,13 @@
|
||||||
- (NSArray *) davResourceType
|
- (NSArray *) davResourceType
|
||||||
{
|
{
|
||||||
NSMutableArray *resourceType;
|
NSMutableArray *resourceType;
|
||||||
NSArray *cardDavCollection;
|
NSArray *type;
|
||||||
|
|
||||||
cardDavCollection
|
|
||||||
= [NSArray arrayWithObjects: @"addressbook",
|
|
||||||
@"urn:ietf:params:xml:ns:carddav", nil];
|
|
||||||
|
|
||||||
resourceType = [NSMutableArray arrayWithArray: [super davResourceType]];
|
resourceType = [NSMutableArray arrayWithArray: [super davResourceType]];
|
||||||
[resourceType addObject: cardDavCollection];
|
type = [NSArray arrayWithObjects: @"addressbook", XMLNS_CARDDAV, nil];
|
||||||
|
[resourceType addObject: type];
|
||||||
|
type = [NSArray arrayWithObjects: @"directory", XMLNS_CARDDAV, nil];
|
||||||
|
[resourceType addObject: type];
|
||||||
|
|
||||||
return resourceType;
|
return resourceType;
|
||||||
}
|
}
|
||||||
|
@ -350,6 +356,273 @@
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *) _deduceObjectNameFromURL: (NSString *) url
|
||||||
|
fromBaseURL: (NSString *) baseURL
|
||||||
|
{
|
||||||
|
NSRange urlRange;
|
||||||
|
NSString *name;
|
||||||
|
|
||||||
|
urlRange = [url rangeOfString: baseURL];
|
||||||
|
if (urlRange.location != NSNotFound)
|
||||||
|
{
|
||||||
|
name = [url substringFromIndex: NSMaxRange (urlRange)];
|
||||||
|
if ([name hasPrefix: @"/"])
|
||||||
|
name = [name substringFromIndex: 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
name = nil;
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: multiget reorg */
|
||||||
|
- (NSString *) _nodeTagForProperty: (NSString *) property
|
||||||
|
{
|
||||||
|
NSString *namespace, *nodeName, *nsRep;
|
||||||
|
NSRange nsEnd;
|
||||||
|
|
||||||
|
nsEnd = [property rangeOfString: @"}"];
|
||||||
|
namespace
|
||||||
|
= [property substringFromRange: NSMakeRange (1, nsEnd.location - 1)];
|
||||||
|
nodeName = [property substringFromIndex: nsEnd.location + 1];
|
||||||
|
if ([namespace isEqualToString: XMLNS_CARDDAV])
|
||||||
|
nsRep = @"C";
|
||||||
|
else
|
||||||
|
nsRep = @"D";
|
||||||
|
|
||||||
|
return [NSString stringWithFormat: @"%@:%@", nsRep, nodeName];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) _nodeTag: (NSString *) property
|
||||||
|
{
|
||||||
|
static NSMutableDictionary *tags = nil;
|
||||||
|
NSString *nodeTag;
|
||||||
|
|
||||||
|
if (!tags)
|
||||||
|
tags = [NSMutableDictionary new];
|
||||||
|
nodeTag = [tags objectForKey: property];
|
||||||
|
if (!nodeTag)
|
||||||
|
{
|
||||||
|
nodeTag = [self _nodeTagForProperty: property];
|
||||||
|
[tags setObject: nodeTag forKey: property];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString **) _properties: (NSString **) properties
|
||||||
|
count: (unsigned int) propertiesCount
|
||||||
|
ofObject: (NSDictionary *) object
|
||||||
|
{
|
||||||
|
SOGoContactLDIFEntry *ldifEntry;
|
||||||
|
NSString **currentProperty;
|
||||||
|
NSString **values, **currentValue;
|
||||||
|
SEL methodSel;
|
||||||
|
|
||||||
|
// NSLog (@"_properties:ofObject:: %@", [NSDate date]);
|
||||||
|
|
||||||
|
values = NSZoneMalloc (NULL,
|
||||||
|
(propertiesCount + 1) * sizeof (NSString *));
|
||||||
|
*(values + propertiesCount) = nil;
|
||||||
|
|
||||||
|
ldifEntry = [SOGoContactLDIFEntry
|
||||||
|
contactEntryWithName: [object objectForKey: @"c_name"]
|
||||||
|
withLDIFEntry: object
|
||||||
|
inContainer: self];
|
||||||
|
currentProperty = properties;
|
||||||
|
currentValue = values;
|
||||||
|
while (*currentProperty)
|
||||||
|
{
|
||||||
|
methodSel = SOGoSelectorForPropertyGetter (*currentProperty);
|
||||||
|
if (methodSel && [ldifEntry respondsToSelector: methodSel])
|
||||||
|
*currentValue = [[ldifEntry performSelector: methodSel]
|
||||||
|
stringByEscapingXMLString];
|
||||||
|
currentProperty++;
|
||||||
|
currentValue++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSLog (@"/_properties:ofObject:: %@", [NSDate date]);
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) _propstats: (NSString **) properties
|
||||||
|
count: (unsigned int) propertiesCount
|
||||||
|
ofObject: (NSDictionary *) object
|
||||||
|
{
|
||||||
|
NSMutableArray *propstats, *properties200, *properties404, *propDict;
|
||||||
|
NSString **property, **values, **currentValue;
|
||||||
|
NSString *propertyValue, *nodeTag;
|
||||||
|
|
||||||
|
// NSLog (@"_propstats:ofObject:: %@", [NSDate date]);
|
||||||
|
|
||||||
|
propstats = [NSMutableArray array];
|
||||||
|
|
||||||
|
properties200 = [NSMutableArray array];
|
||||||
|
properties404 = [NSMutableArray array];
|
||||||
|
|
||||||
|
values = [self _properties: properties count: propertiesCount
|
||||||
|
ofObject: object];
|
||||||
|
currentValue = values;
|
||||||
|
|
||||||
|
property = properties;
|
||||||
|
while (*property)
|
||||||
|
{
|
||||||
|
nodeTag = [self _nodeTag: *property];
|
||||||
|
if (*currentValue)
|
||||||
|
{
|
||||||
|
propertyValue = [NSString stringWithFormat: @"<%@>%@</%@>",
|
||||||
|
nodeTag, *currentValue, nodeTag];
|
||||||
|
propDict = properties200;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
propertyValue = [NSString stringWithFormat: @"<%@/>", nodeTag];
|
||||||
|
propDict = properties404;
|
||||||
|
}
|
||||||
|
[propDict addObject: propertyValue];
|
||||||
|
property++;
|
||||||
|
currentValue++;
|
||||||
|
}
|
||||||
|
free (values);
|
||||||
|
|
||||||
|
if ([properties200 count])
|
||||||
|
[propstats addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
properties200, @"properties",
|
||||||
|
@"HTTP/1.1 200 OK", @"status",
|
||||||
|
nil]];
|
||||||
|
if ([properties404 count])
|
||||||
|
[propstats addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
properties404, @"properties",
|
||||||
|
@"HTTP/1.1 404 Not Found", @"status",
|
||||||
|
nil]];
|
||||||
|
// NSLog (@"/_propstats:ofObject:: %@", [NSDate date]);
|
||||||
|
|
||||||
|
return propstats;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _appendPropstat: (NSDictionary *) propstat
|
||||||
|
toBuffer: (NSMutableString *) r
|
||||||
|
{
|
||||||
|
NSArray *properties;
|
||||||
|
unsigned int count, max;
|
||||||
|
|
||||||
|
[r appendString: @"<D:propstat><D:prop>"];
|
||||||
|
properties = [propstat objectForKey: @"properties"];
|
||||||
|
max = [properties count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
[r appendString: [properties objectAtIndex: count]];
|
||||||
|
[r appendString: @"</D:prop><D:status>"];
|
||||||
|
[r appendString: [propstat objectForKey: @"status"]];
|
||||||
|
[r appendString: @"</D:status></D:propstat>"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) appendObject: (NSDictionary *) object
|
||||||
|
properties: (NSString **) properties
|
||||||
|
count: (unsigned int) propertiesCount
|
||||||
|
withBaseURL: (NSString *) baseURL
|
||||||
|
toBuffer: (NSMutableString *) r
|
||||||
|
{
|
||||||
|
NSArray *propstats;
|
||||||
|
unsigned int count, max;
|
||||||
|
|
||||||
|
[r appendFormat: @"<D:response><D:href>"];
|
||||||
|
[r appendString: baseURL];
|
||||||
|
[r appendString: [[object objectForKey: @"c_name"] stringByEscapingURL]];
|
||||||
|
[r appendString: @"</D:href>"];
|
||||||
|
|
||||||
|
// NSLog (@"(appendPropstats...): %@", [NSDate date]);
|
||||||
|
propstats = [self _propstats: properties count: propertiesCount
|
||||||
|
ofObject: object];
|
||||||
|
max = [propstats count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
[self _appendPropstat: [propstats objectAtIndex: count]
|
||||||
|
toBuffer: r];
|
||||||
|
// NSLog (@"/(appendPropstats...): %@", [NSDate date]);
|
||||||
|
|
||||||
|
[r appendString: @"</D:response>"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) appendMissingObjectRef: (NSString *) href
|
||||||
|
toBuffer: (NSMutableString *) r
|
||||||
|
{
|
||||||
|
[r appendString: @"<D:response><D:href>"];
|
||||||
|
[r appendString: href];
|
||||||
|
[r appendString: @"</D:href><D:status>HTTP/1.1 404 Not Found</D:status></D:response>"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _appendComponentProperties: (NSArray *) properties
|
||||||
|
matchingURLs: (id <DOMNodeList>) refs
|
||||||
|
toResponse: (WOResponse *) response
|
||||||
|
{
|
||||||
|
NSObject <DOMElement> *element;
|
||||||
|
NSString *url, *baseURL, *cname;
|
||||||
|
NSString **propertiesArray;
|
||||||
|
NSMutableString *buffer;
|
||||||
|
unsigned int count, max, propertiesCount;
|
||||||
|
|
||||||
|
baseURL = [self davURLAsString];
|
||||||
|
#warning review this when fixing http://www.scalableogo.org/bugs/view.php?id=276
|
||||||
|
if (![baseURL hasSuffix: @"/"])
|
||||||
|
baseURL = [NSString stringWithFormat: @"%@/", baseURL];
|
||||||
|
|
||||||
|
propertiesArray = [properties asPointersOfObjects];
|
||||||
|
propertiesCount = [properties count];
|
||||||
|
|
||||||
|
max = [refs length];
|
||||||
|
buffer = [NSMutableString stringWithCapacity: max*512];
|
||||||
|
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
element = [refs objectAtIndex: count];
|
||||||
|
url = [[[element firstChild] nodeValue] stringByUnescapingURL];
|
||||||
|
cname = [self _deduceObjectNameFromURL: url fromBaseURL: baseURL];
|
||||||
|
if (cname)
|
||||||
|
[self appendObject: [source lookupContactEntry: cname]
|
||||||
|
properties: propertiesArray
|
||||||
|
count: propertiesCount
|
||||||
|
withBaseURL: baseURL
|
||||||
|
toBuffer: buffer];
|
||||||
|
else
|
||||||
|
[self appendMissingObjectRef: url
|
||||||
|
toBuffer: buffer];
|
||||||
|
}
|
||||||
|
[response appendContentString: buffer];
|
||||||
|
// NSLog (@"/adding properties with url");
|
||||||
|
|
||||||
|
NSZoneFree (NULL, propertiesArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (WOResponse *) performMultigetInContext: (WOContext *) queryContext
|
||||||
|
inNamespace: (NSString *) namespace
|
||||||
|
{
|
||||||
|
WOResponse *r;
|
||||||
|
id <DOMDocument> document;
|
||||||
|
DOMElement *documentElement, *propElement;
|
||||||
|
|
||||||
|
r = [context response];
|
||||||
|
[r prepareDAVResponse];
|
||||||
|
[r appendContentString:
|
||||||
|
[NSString stringWithFormat: @"<D:multistatus xmlns:D=\"DAV:\""
|
||||||
|
@" xmlns:C=\"%@\">", namespace]];
|
||||||
|
document = [[queryContext request] contentAsDOMDocument];
|
||||||
|
documentElement = (DOMElement *) [document documentElement];
|
||||||
|
propElement = [documentElement firstElementWithTag: @"prop"
|
||||||
|
inNamespace: @"DAV:"];
|
||||||
|
[self _appendComponentProperties: [propElement flatPropertyNameOfSubElements]
|
||||||
|
matchingURLs: [documentElement getElementsByTagName: @"href"]
|
||||||
|
toResponse: r];
|
||||||
|
[r appendContentString:@"</D:multistatus>"];
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) davAddressbookMultiget: (id) queryContext
|
||||||
|
{
|
||||||
|
return [self performMultigetInContext: queryContext
|
||||||
|
inNamespace: XMLNS_CARDDAV];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString *) davDisplayName
|
- (NSString *) davDisplayName
|
||||||
{
|
{
|
||||||
return displayName;
|
return displayName;
|
||||||
|
|
|
@ -73,17 +73,17 @@
|
||||||
etagLine = [NSString stringWithFormat: @"<D:getetag>%@</D:getetag>",
|
etagLine = [NSString stringWithFormat: @"<D:getetag>%@</D:getetag>",
|
||||||
[component davEntityTag]];
|
[component davEntityTag]];
|
||||||
[r appendContentString: etagLine];
|
[r appendContentString: etagLine];
|
||||||
[r appendContentString: @"</D:prop>"
|
[r appendContentString: @"<C:address-data>"];
|
||||||
@"<D:status>HTTP/1.1 200 OK</D:status>"
|
|
||||||
@"</D:propstat>"
|
|
||||||
@"<C:addressbook-data>"];
|
|
||||||
contactString = [[component contentAsString] stringByEscapingXMLString];
|
contactString = [[component contentAsString] stringByEscapingXMLString];
|
||||||
[r appendContentString: contactString];
|
[r appendContentString: contactString];
|
||||||
[r appendContentString: @"</C:addressbook-data>"
|
|
||||||
@"<C:address-data>"];
|
|
||||||
[r appendContentString: contactString];
|
|
||||||
[r appendContentString: @"</C:address-data>"
|
[r appendContentString: @"</C:address-data>"
|
||||||
@"</D:response>"];
|
@"<C:addressbook-data>"];
|
||||||
|
[r appendContentString: contactString];
|
||||||
|
[r appendContentString: @"</C:addressbook-data>"
|
||||||
|
@"</D:prop>"
|
||||||
|
@"<D:status>HTTP/1.1 200 OK</D:status>"
|
||||||
|
@"</D:propstat>"
|
||||||
|
@"</D:response>"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@
|
||||||
|
|
||||||
return ([newString isEqualToString: @"sn"]
|
return ([newString isEqualToString: @"sn"]
|
||||||
|| [newString isEqualToString: @"givenname"]
|
|| [newString isEqualToString: @"givenname"]
|
||||||
|
|| [newString isEqualToString: @"email"]
|
||||||
|| [newString isEqualToString: @"mail"]
|
|| [newString isEqualToString: @"mail"]
|
||||||
|| [newString isEqualToString: @"telephonenumber"]);
|
|| [newString isEqualToString: @"telephonenumber"]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#import <SaxObjC/XMLNamespaces.h>
|
#import <SaxObjC/XMLNamespaces.h>
|
||||||
|
|
||||||
#import <SOGo/SOGoUser.h>
|
#import <SOGo/SOGoUser.h>
|
||||||
|
#import <SOGo/SOGoUserManager.h>
|
||||||
#import <SOGo/NSObject+DAV.h>
|
#import <SOGo/NSObject+DAV.h>
|
||||||
#import <SOGo/NSString+DAV.h>
|
#import <SOGo/NSString+DAV.h>
|
||||||
|
|
||||||
|
@ -58,4 +59,30 @@
|
||||||
return [NSArray arrayWithObject: tag];
|
return [NSArray arrayWithObject: tag];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray *) davDirectoryGateway
|
||||||
|
{
|
||||||
|
NSArray *tag, *sources;
|
||||||
|
SOGoContactFolders *parent;
|
||||||
|
SOGoUserManager *um;
|
||||||
|
NSString *domain, *url;
|
||||||
|
|
||||||
|
domain = [[context activeUser] domain];
|
||||||
|
um = [SOGoUserManager sharedUserManager];
|
||||||
|
sources = [um addressBookSourceIDsInDomain: domain];
|
||||||
|
if ([sources count] > 0)
|
||||||
|
{
|
||||||
|
parent = [self privateContacts: @"Contacts" inContext: context];
|
||||||
|
url = [NSString stringWithFormat: @"%@%@/", [parent davURLAsString],
|
||||||
|
[sources objectAtIndex: 0]];
|
||||||
|
tag = [NSArray arrayWithObject:
|
||||||
|
[NSArray arrayWithObjects: @"href", @"DAV:", @"D",
|
||||||
|
url, nil]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tag = nil;
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -830,6 +830,8 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField
|
||||||
NSEnumerator *entries;
|
NSEnumerator *entries;
|
||||||
NGLdapEntry *currentEntry;
|
NGLdapEntry *currentEntry;
|
||||||
NGLdapConnection *ldapConnection;
|
NGLdapConnection *ldapConnection;
|
||||||
|
EOQualifier *qualifier;
|
||||||
|
NSMutableString *qs;
|
||||||
NSString *value;
|
NSString *value;
|
||||||
NSArray *attributes;
|
NSArray *attributes;
|
||||||
NSMutableArray *ids;
|
NSMutableArray *ids;
|
||||||
|
@ -838,17 +840,23 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField
|
||||||
|
|
||||||
ldapConnection = [self _ldapConnection];
|
ldapConnection = [self _ldapConnection];
|
||||||
attributes = [NSArray arrayWithObject: IDField];
|
attributes = [NSArray arrayWithObject: IDField];
|
||||||
|
|
||||||
|
qs = [NSMutableString stringWithFormat: @"(%@='*')", CNField];
|
||||||
|
if ([_filter length])
|
||||||
|
[qs appendFormat: @" AND %@", _filter];
|
||||||
|
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||||
|
|
||||||
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame)
|
||||||
entries = [ldapConnection baseSearchAtBaseDN: baseDN
|
entries = [ldapConnection baseSearchAtBaseDN: baseDN
|
||||||
qualifier: nil
|
qualifier: qualifier
|
||||||
attributes: attributes];
|
attributes: attributes];
|
||||||
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame)
|
||||||
entries = [ldapConnection flatSearchAtBaseDN: baseDN
|
entries = [ldapConnection flatSearchAtBaseDN: baseDN
|
||||||
qualifier: nil
|
qualifier: qualifier
|
||||||
attributes: attributes];
|
attributes: attributes];
|
||||||
else
|
else
|
||||||
entries = [ldapConnection deepSearchAtBaseDN: baseDN
|
entries = [ldapConnection deepSearchAtBaseDN: baseDN
|
||||||
qualifier: nil
|
qualifier: qualifier
|
||||||
attributes: attributes];
|
attributes: attributes];
|
||||||
|
|
||||||
while ((currentEntry = [entries nextObject]))
|
while ((currentEntry = [entries nextObject]))
|
||||||
|
|
Loading…
Reference in a new issue