See ChangeLog
Monotone-Parent: ed15d4f340fd47347d881c8826eb40a2dc22763d Monotone-Revision: d669b0b3e321e22c68d092f984d543560ae1af0e Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-01-12T20:01:34maint-2.0.2
parent
335ba606b4
commit
ccf847f555
33
ChangeLog
33
ChangeLog
|
@ -1,3 +1,36 @@
|
|||
2012-01-12 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoSource.h (-bindDN, -bindPassword)
|
||||
(-MSExchangeHostname): new accessors to the SOGoDNSource protocol.
|
||||
|
||||
* SoObjects/SOGo/LDAPSource.m (-_convertLDAPEntryToContact:):
|
||||
added a reference to the instance source in the returned dictionary.
|
||||
|
||||
* SoObjects/SOGo/SOGoUserManager.m
|
||||
(-_compactAndCompleteContacts:): keep the source instance in the
|
||||
returned dictionary.
|
||||
|
||||
* UI/MainUI/SOGoUserHomePage.m (-readFreeBusyAction): the http
|
||||
post can now include an optional "uid" parameter to perform the
|
||||
freebusy lookup on the user corresponding to the specified
|
||||
uid. This covers the special case where we want to query a user
|
||||
from a contact source (not an authentication source) and for which
|
||||
external freebusy information is available (currently limited to a
|
||||
Microsoft Exchange server with Web Services enabled).
|
||||
|
||||
* SoObjects/Appointments/SOGoFreeBusyObject.m
|
||||
(-fetchFreeBusyInfosFrom:to:forUser:): new method currently
|
||||
limited perform a SOAP request to a MS Exhange server to retrieve
|
||||
the freebusy information of a user.
|
||||
|
||||
* UI/WebServerResources/UIxAttendeesEditor.js
|
||||
(performSearchCallback): if a matching contact has the
|
||||
"isMSExchange" attribute, prefix the uid with the login uid.
|
||||
(_performAjaxRequest): query the freebusy information from the
|
||||
login user (/SOGo/so/<loginuser>/freebusy.ifb/ajaxRead?uid=<contact>)
|
||||
when a contact uid is specified. Otherwise, perform the query on
|
||||
the user instance as usual (/SOGo/so/<contactuser>/freebusy.ifb/ajaxRead).
|
||||
|
||||
2012-01-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
|
|
@ -42,10 +42,15 @@ Appointments_OBJC_FILES = \
|
|||
SOGoAptMailUpdate.m \
|
||||
SOGoAptMailReceipt.m \
|
||||
\
|
||||
SOGoEMailAlarmsManager.m
|
||||
SOGoEMailAlarmsManager.m \
|
||||
\
|
||||
MSExchangeFreeBusySOAPRequest.m \
|
||||
MSExchangeFreeBusy.m
|
||||
|
||||
Appointments_RESOURCE_FILES += \
|
||||
product.plist \
|
||||
\
|
||||
MSExchangeFreeBusySOAPRequest.wo
|
||||
|
||||
Appointments_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
|
@ -53,6 +58,7 @@ Appointments_LOCALIZED_RESOURCE_FILES = Localizable.strings
|
|||
|
||||
ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/
|
||||
ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/
|
||||
ADDITIONAL_LDFLAGS += -lcurl -lgnutls
|
||||
|
||||
-include GNUmakefile.preamble
|
||||
include $(GNUSTEP_MAKEFILES)/wobundle.make
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* MSExchangeFreeBusy.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 Inverse inc.
|
||||
*
|
||||
* Author: Francis Lachapelle <flachapelle@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 MSEXCHANGEFREEBUSY_H
|
||||
#define MSEXCHANGEFREEBUSY_H
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
@class MSExchangeFreeBusyResponse;
|
||||
@class MSExchangeFreeBusyView;
|
||||
|
||||
@interface MSExchangeFreeBusy : NSObject
|
||||
{
|
||||
NSMutableData *curlBody;
|
||||
MSExchangeFreeBusyResponse *response;
|
||||
}
|
||||
|
||||
- (size_t) curlWritePtr: (void *) inPtr
|
||||
size: (size_t) inSize
|
||||
number: (size_t) inNumber;
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate
|
||||
forEmail: (NSString *) email
|
||||
inSource: (NSObject <SOGoDNSource> *) source
|
||||
// fromServer: (NSString *) hostname
|
||||
inContext: (WOContext *) context;
|
||||
|
||||
@end
|
||||
|
||||
@interface MSExchangeFreeBusyResponse : NSObject
|
||||
{
|
||||
MSExchangeFreeBusyView *view;
|
||||
}
|
||||
|
||||
- (MSExchangeFreeBusyView *) view;
|
||||
|
||||
@end
|
||||
|
||||
@interface MSExchangeFreeBusyView : NSObject
|
||||
{
|
||||
NSString *freeBusyViewType;
|
||||
NSString *mergedFreeBusy;
|
||||
}
|
||||
|
||||
- (NSArray *) infosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MSEXCHANGEFREEBUSY_H */
|
|
@ -0,0 +1,350 @@
|
|||
/* MSExchangeFreeBusy.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 Inverse inc.
|
||||
*
|
||||
* Author: Francis Lachapelle <flachapelle@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/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <SaxObjC/SaxObjC.h>
|
||||
#import <SaxObjC/SaxMethodCallHandler.h>
|
||||
#import <SaxObjC/SaxObjectDecoder.h>
|
||||
#import <SaxObjC/SaxXMLReaderFactory.h>
|
||||
|
||||
#import <curl/curl.h>
|
||||
|
||||
#import <SOGo/SOGoSource.h>
|
||||
|
||||
#import "MSExchangeFreeBusySOAPRequest.h"
|
||||
#import "MSExchangeFreeBusy.h"
|
||||
|
||||
size_t curlBodyFunction(void *ptr, size_t size, size_t nmemb, void *inSelf)
|
||||
{
|
||||
return [(MSExchangeFreeBusy *)inSelf curlWritePtr:ptr size:size number:nmemb];
|
||||
}
|
||||
|
||||
@implementation MSExchangeFreeBusy
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
curlBody = [[NSMutableData alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[curlBody release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (size_t) curlWritePtr:(void *)inPtr
|
||||
size:(size_t)inSize
|
||||
number:(size_t)inNumber
|
||||
{
|
||||
size_t written = inSize*inNumber;
|
||||
NSData *data = [NSData dataWithBytes:inPtr length:written];
|
||||
[curlBody appendData: data];
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the user availability by sending a SOAP request to a MS Exchange server (EWS).
|
||||
* @param startDate the beginning of the covered period
|
||||
* @param endDate the ending of the covered period
|
||||
* @param email the address of the user to query
|
||||
* @param source the SOGo source of the user
|
||||
* @param context the current WO context
|
||||
* @return an array of dictionaries containing the start and end dates of each busy period
|
||||
* @see <http://msdn.microsoft.com/en-us/library/aa563800(v=EXCHG.140).aspx>
|
||||
*/
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate
|
||||
forEmail: (NSString *) email
|
||||
inSource: (NSObject <SOGoDNSource> *) source
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
static id<NSObject,SaxXMLReader> parser = nil;
|
||||
static SaxObjectDecoder *sax = nil;
|
||||
|
||||
MSExchangeFreeBusySOAPRequest *soapRequest;
|
||||
MSExchangeFreeBusyResponse *freeBusyResponse;
|
||||
NSString *rawRequest, *url, *body, *hostname, *httpauth, *authname, *password;
|
||||
NSArray *infos = nil;
|
||||
NSDictionary *root;
|
||||
|
||||
CURL *curl;
|
||||
struct curl_slist *headerlist=NULL;
|
||||
CURLcode rc;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
|
||||
// Construct SOAP GetUserAvailabilityRequest from .wo template
|
||||
soapRequest = [[WOApplication application] pageWithName: @"MSExchangeFreeBusySOAPRequest"
|
||||
inContext: context];
|
||||
[soapRequest setAddress: email
|
||||
from: startDate
|
||||
to: endDate];
|
||||
rawRequest = [[soapRequest generateResponse] contentAsString];
|
||||
|
||||
if ([rawRequest length])
|
||||
{
|
||||
// Prepare HTTPS post using libcurl
|
||||
curl_global_init(CURL_GLOBAL_SSL);
|
||||
curl = curl_easy_init();
|
||||
headerlist = curl_slist_append(headerlist, "Content-Type: text/xml; charset=utf-8");
|
||||
if (curl)
|
||||
{
|
||||
hostname = [source MSExchangeHostname];
|
||||
authname = [source lookupLoginByDN: [source bindDN]];
|
||||
password = [source bindPassword];
|
||||
error[0] = 0;
|
||||
if ([authname length] && [password length])
|
||||
{
|
||||
httpauth = [NSString stringWithFormat: @"%@:%@", authname, password];
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, [httpauth UTF8String]);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
|
||||
}
|
||||
url = [NSString stringWithFormat: @"https://%@/ews/Exchange.asmx", hostname];
|
||||
curl_easy_setopt(curl, CURLOPT_URL, [url UTF8String]);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, [rawRequest UTF8String]);
|
||||
//curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curlHeaderFunction);
|
||||
//curl_easy_setopt(curl, CURLOPT_HEADER, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlBodyFunction);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, self);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error);
|
||||
|
||||
// Perform SOAP request
|
||||
rc = curl_easy_perform(curl);
|
||||
if (rc != 0)
|
||||
[self errorWithFormat: @"CURL error while accessing %@ (%d): ", url, rc, [NSString stringWithCString: error]];
|
||||
curl_easy_cleanup(curl);
|
||||
curl_slist_free_all(headerlist);
|
||||
|
||||
if ([curlBody length])
|
||||
{
|
||||
// Parse SOAP response
|
||||
if (parser == nil)
|
||||
{
|
||||
parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
|
||||
createXMLReaderForMimeType:@"text/xml"];
|
||||
[parser retain];
|
||||
}
|
||||
if (sax == nil && parser != nil)
|
||||
{
|
||||
sax = [[SaxObjectDecoder alloc] initWithMappingAtPath:@"./MSExchangeFreeBusySOAPResponseMap.plist"];
|
||||
[parser setContentHandler:sax];
|
||||
//[parser setErrorHandler:sax];
|
||||
}
|
||||
|
||||
body = [[NSString alloc] initWithData:curlBody encoding:NSASCIIStringEncoding];
|
||||
[body autorelease];
|
||||
|
||||
[parser parseFromSource: body];
|
||||
root = [sax rootObject];
|
||||
freeBusyResponse = [[root objectForKey: @"Body"] objectForKey: @"GetUserAvailabilityResponse"];
|
||||
|
||||
// Extract busy periods
|
||||
infos = [[freeBusyResponse view] infosFrom: startDate to: endDate];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return infos;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MSExchangeFreeBusyResponse
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
view = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[view release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (MSExchangeFreeBusyView *) view
|
||||
{
|
||||
return self->view;
|
||||
}
|
||||
|
||||
- (void) setFreeBusyResponseArray: (NSDictionary *) _value
|
||||
{
|
||||
NSString *responseCode;
|
||||
NSArray *responses;
|
||||
NSDictionary *response;
|
||||
|
||||
view = nil;
|
||||
responses = (NSArray *) [_value objectForKey: @"responses"];
|
||||
|
||||
if ([responses count] != 1)
|
||||
{
|
||||
[self errorWithFormat: @"unexpected number of responses (%i) from SOAP request", [responses count]];
|
||||
}
|
||||
else
|
||||
{
|
||||
response = [responses objectAtIndex: 0];
|
||||
responseCode = [[response objectForKey: @"ResponseMessage"] objectForKey: @"ResponseCode"];
|
||||
if ([responseCode compare: @"NoError"] == NSOrderedSame)
|
||||
{
|
||||
view = [response objectForKey: @"FreeBusyView"];
|
||||
[view retain];
|
||||
}
|
||||
}
|
||||
|
||||
[self logWithFormat: @"SOAP Response: %@", self->view];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MSExchangeFreeBusyView
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
freeBusyViewType = nil;
|
||||
mergedFreeBusy = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[freeBusyViewType release];
|
||||
[mergedFreeBusy release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setFreeBusyViewType: (NSString *) _value
|
||||
{
|
||||
ASSIGN(freeBusyViewType, _value);
|
||||
}
|
||||
|
||||
- (void) setMergedFreeBusy: (NSString *) _value
|
||||
{
|
||||
ASSIGN(mergedFreeBusy, _value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the "DetailedMerged" representation of the freebusy information and
|
||||
* extract the busy periods.
|
||||
* @param startDate the beginning of the covered period
|
||||
* @param endDate the ending of the covered period
|
||||
* @return an array of dictionaries containing the start and end dates of each busy period
|
||||
* @see <http://msdn.microsoft.com/en-us/library/aa565898(v=EXCHG.140).aspx>
|
||||
*/
|
||||
- (NSArray *) infosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate
|
||||
{
|
||||
NSMutableArray *infos;
|
||||
NSCalendarDate *currentDate, *currentStartDate, *currentEndDate;
|
||||
unsigned int count;
|
||||
|
||||
infos = [NSMutableArray array];
|
||||
currentStartDate = nil;
|
||||
currentDate = startDate;
|
||||
count = 0;
|
||||
|
||||
while (([currentDate compare: endDate] == NSOrderedAscending ||
|
||||
[currentDate compare: endDate] == NSOrderedSame) &&
|
||||
[mergedFreeBusy length] > count)
|
||||
{
|
||||
switch ([mergedFreeBusy characterAtIndex: count])
|
||||
{
|
||||
case '0': // Free
|
||||
if (currentStartDate)
|
||||
{
|
||||
currentEndDate = currentDate;
|
||||
[infos addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool: YES], @"c_isopaque",
|
||||
currentStartDate, @"startDate",
|
||||
currentEndDate, @"endDate", nil]];
|
||||
[self debugWithFormat: @"Busy period from %@ to %@", currentStartDate, currentEndDate];
|
||||
currentStartDate = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case '1': // Tentative
|
||||
case '2': // Busy
|
||||
case '3': // Out of Office
|
||||
if (currentStartDate == nil)
|
||||
currentStartDate = currentDate;
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
currentDate = [currentDate dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 15 seconds: 0];
|
||||
}
|
||||
|
||||
if (currentStartDate)
|
||||
{
|
||||
currentEndDate = currentDate;
|
||||
[infos addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool: YES], @"c_isopaque",
|
||||
currentStartDate, @"startDate",
|
||||
currentEndDate, @"endDate", nil]];
|
||||
[self debugWithFormat: @"Busy period from %@ to %@", currentStartDate, currentEndDate];
|
||||
}
|
||||
|
||||
return infos;
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
NSMutableString *s;
|
||||
|
||||
s = [NSMutableString stringWithCapacity: 64];
|
||||
[s appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
|
||||
if (freeBusyViewType)
|
||||
[s appendFormat:@" freeBusyViewType='%@'", freeBusyViewType];
|
||||
if (mergedFreeBusy)
|
||||
[s appendFormat:@" mergedFreeBusy='%@'", mergedFreeBusy];
|
||||
[s appendString:@">"];
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright (C) 2012 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
SOGo 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 Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with SOGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __Appointments_MSExchangeFreeBusySOAPRequest_H_
|
||||
#define __Appointments_MSExchangeFreeBusySOAPRequest_H_
|
||||
|
||||
#include <NGObjWeb/SoComponent.h>
|
||||
|
||||
@class NSCalendarDate;
|
||||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
@class NSTimeZone;
|
||||
@class iCalEvent;
|
||||
|
||||
/*
|
||||
* NOTE: We inherit from SoComponent in order to get the correct
|
||||
* resourceManager required for this product
|
||||
*/
|
||||
@interface MSExchangeFreeBusySOAPRequest : SoComponent
|
||||
{
|
||||
NSString *address;
|
||||
NSTimeZone *timeZone;
|
||||
NSCalendarDate *startDate;
|
||||
NSCalendarDate *endDate;
|
||||
int interval;
|
||||
}
|
||||
|
||||
- (void) setAddress: (NSString *) _address
|
||||
from: (NSCalendarDate *) _startDate
|
||||
to: (NSCalendarDate *) _endDate;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __Appointments_MSExchangeFreeBusySOAPRequest_H_ */
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright (C) 2012 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
SOGo 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 Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with SOGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSCharacterSet.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
|
||||
#import <NGObjWeb/WOActionResults.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/NSObject+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoDateFormatter.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
|
||||
#import "MSExchangeFreeBusySOAPRequest.h"
|
||||
|
||||
@implementation MSExchangeFreeBusySOAPRequest
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
address = nil;
|
||||
timeZone = [NSTimeZone timeZoneWithAbbreviation: @"GMT"];
|
||||
[timeZone retain];
|
||||
startDate = nil;
|
||||
endDate = nil;
|
||||
interval = 15;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[address release];
|
||||
[timeZone release];
|
||||
[startDate release];
|
||||
[endDate release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setAddress: (NSString *) newAddress
|
||||
from: (NSCalendarDate *) newStartDate
|
||||
to: (NSCalendarDate *) newEndDate
|
||||
{
|
||||
ASSIGN(address, newAddress);
|
||||
ASSIGN(startDate, newStartDate);
|
||||
ASSIGN(endDate, newEndDate);
|
||||
|
||||
[startDate setTimeZone: timeZone];
|
||||
[endDate setTimeZone: timeZone];
|
||||
}
|
||||
|
||||
- (NSString *) serverVersion
|
||||
{
|
||||
return @"Exchange2007_SP1";
|
||||
}
|
||||
|
||||
- (NSString *) address
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
- (NSString *) startTime
|
||||
{
|
||||
return [startDate descriptionWithCalendarFormat: @"%Y-%m-%dT%H:%M:%S"];
|
||||
}
|
||||
|
||||
- (NSString *) endTime
|
||||
{
|
||||
return [endDate descriptionWithCalendarFormat: @"%Y-%m-%dT%H:%M:%S"];
|
||||
}
|
||||
|
||||
- (NSString *) interval
|
||||
{
|
||||
return [NSString stringWithFormat: @"%i", interval];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" standalone="yes"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
|
||||
<soap:Header>
|
||||
<t:RequestServerVersion Version="<#serverVersion/>"/>
|
||||
</soap:Header>
|
||||
<soap:Body>
|
||||
<GetUserAvailabilityRequest xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
|
||||
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
|
||||
<t:TimeZone xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
|
||||
<Bias>0</Bias>
|
||||
<StandardTime>
|
||||
<Bias>0</Bias>
|
||||
<Time>00:00:00</Time>
|
||||
<DayOrder>1</DayOrder>
|
||||
<Month>1</Month>
|
||||
<DayOfWeek>Sunday</DayOfWeek>
|
||||
</StandardTime>
|
||||
<DaylightTime>
|
||||
<Bias>0</Bias>
|
||||
<Time>00:00:00</Time>
|
||||
<DayOrder>1</DayOrder>
|
||||
<Month>1</Month>
|
||||
<DayOfWeek>Sunday</DayOfWeek>
|
||||
</DaylightTime>
|
||||
</t:TimeZone>
|
||||
<MailboxDataArray>
|
||||
<t:MailboxData>
|
||||
<t:Email>
|
||||
<t:Address><#address/></t:Address>
|
||||
</t:Email>
|
||||
<t:AttendeeType>Required</t:AttendeeType>
|
||||
<t:ExcludeConflicts>false</t:ExcludeConflicts>
|
||||
</t:MailboxData>
|
||||
</MailboxDataArray>
|
||||
<t:FreeBusyViewOptions>
|
||||
<t:TimeWindow>
|
||||
<t:StartTime><#startTime/></t:StartTime>
|
||||
<t:EndTime><#endTime/></t:EndTime>
|
||||
</t:TimeWindow>
|
||||
<t:MergedFreeBusyIntervalInMinutes>15</t:MergedFreeBusyIntervalInMinutes>
|
||||
<t:RequestedView>DetailedMerged</t:RequestedView>
|
||||
</t:FreeBusyViewOptions>
|
||||
</GetUserAvailabilityRequest>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
|
@ -0,0 +1,24 @@
|
|||
serverVersion: WOString {
|
||||
value = serverVersion;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
address: WOString {
|
||||
value = address;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
startTime: WOString {
|
||||
value = startTime;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
endTime: WOString {
|
||||
value = endTime;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
interval: WOString {
|
||||
value = interval;
|
||||
escapeHTML = NO;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
{ /* -*-java-*- */
|
||||
"http://schemas.xmlsoap.org/soap/envelope/" = {
|
||||
Envelope = {
|
||||
class = NSMutableDictionary;
|
||||
};
|
||||
|
||||
Header = {
|
||||
class = NSMutableDictionary;
|
||||
attributes = {
|
||||
serverVersionInfo = ServerVersionInfo;
|
||||
};
|
||||
};
|
||||
|
||||
Body = {
|
||||
class = NSMutableDictionary;
|
||||
};
|
||||
};
|
||||
|
||||
"http://schemas.microsoft.com/exchange/services/2006/messages" = {
|
||||
GetUserAvailabilityResponse = {
|
||||
class = MSExchangeFreeBusyResponse;
|
||||
attributes = {
|
||||
FreeBusyResponseArray = FreeBusyResponseArray;
|
||||
};
|
||||
};
|
||||
|
||||
FreeBusyResponseArray = {
|
||||
class = NSMutableDictionary;
|
||||
ToManyRelationships = {
|
||||
responses = ( FreeBusyResponse );
|
||||
};
|
||||
};
|
||||
|
||||
ResponseMessage = {
|
||||
class = NSMutableDictionary;
|
||||
};
|
||||
|
||||
ResponseCode = {
|
||||
class = NSString;
|
||||
};
|
||||
|
||||
FreeBusyResponse = {
|
||||
class = NSMutableDictionary;
|
||||
};
|
||||
|
||||
FreeBusyView = {
|
||||
class = MSExchangeFreeBusyView;
|
||||
attributes = {
|
||||
FreeBusyViewType = freeBusyViewType;
|
||||
MergedFreeBusy = mergedFreeBusy;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
"http://schemas.microsoft.com/exchange/services/2006/types" = {
|
||||
FreeBusyViewType = {
|
||||
class = NSString;
|
||||
};
|
||||
MergedFreeBusy = {
|
||||
class = NSString;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2007-2011 Inverse inc.
|
||||
Copyright (C) 2007-2012 Inverse inc.
|
||||
Copyright (C) 2000-2004 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo
|
||||
|
@ -38,8 +38,6 @@
|
|||
@class iCalPerson;
|
||||
|
||||
@interface SOGoFreeBusyObject : SOGoObject
|
||||
{
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
|
@ -55,7 +53,9 @@
|
|||
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
|
||||
to: (NSCalendarDate *) _endDate;
|
||||
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate
|
||||
forUser: (NSString *) uid;
|
||||
@end
|
||||
|
||||
#endif /* __Appointments_SOGoFreeBusyObject_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2007-2011 Inverse inc.
|
||||
Copyright (C) 2007-2012 Inverse inc.
|
||||
Copyright (C) 2000-2004 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo
|
||||
|
@ -21,10 +21,12 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
|
@ -34,6 +36,7 @@
|
|||
|
||||
#import <SOGo/SOGoBuild.h>
|
||||
#import <SOGo/SOGoDomainDefaults.h>
|
||||
#import <SOGo/SOGoSource.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
|
@ -42,6 +45,8 @@
|
|||
#import "SOGoAppointmentFolder.h"
|
||||
#import "SOGoAppointmentFolders.h"
|
||||
|
||||
#import "MSExchangeFreeBusy.h"
|
||||
|
||||
#import "SOGoFreeBusyObject.h"
|
||||
|
||||
@interface SOGoFreeBusyObject (PrivateAPI)
|
||||
|
@ -240,6 +245,60 @@
|
|||
to: _endDate];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch freebusy information for a user that exists in a contact source
|
||||
* (not an authentication source) for which freebusy information is available
|
||||
* (currently limited to a Microsoft Exchange server with Web Services enabled).
|
||||
* @param startDate the beginning of the covered period
|
||||
* @param endDate the ending of the covered period
|
||||
* @param uid the ID of the user within the current domain
|
||||
* @return an array of dictionaries containing the start and end dates of each busy period
|
||||
* @see MSExchangeFreeBusy.m
|
||||
*/
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate
|
||||
forUser: (NSString *) uid
|
||||
{
|
||||
if ([uid length])
|
||||
{
|
||||
SOGoUserManager *um;
|
||||
NSArray *users;
|
||||
NSString *domain, *email;
|
||||
NSDictionary *user;
|
||||
MSExchangeFreeBusy *exchangeFreeBusy;
|
||||
NSObject <SOGoDNSource> *source;
|
||||
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
domain = [[context activeUser] domain];
|
||||
users = [um fetchContactsMatching: uid inDomain: domain];
|
||||
if ([users count] == 1)
|
||||
{
|
||||
user = [users lastObject];
|
||||
email = [user valueForKey: @"c_email"];
|
||||
source = [user objectForKey: @"source"];
|
||||
if ([email length])
|
||||
{
|
||||
exchangeFreeBusy = [[MSExchangeFreeBusy alloc] init];
|
||||
[exchangeFreeBusy autorelease];
|
||||
|
||||
return [exchangeFreeBusy fetchFreeBusyInfosFrom: startDate
|
||||
to: endDate
|
||||
forEmail: email
|
||||
inSource: source
|
||||
inContext: context];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return [self fetchFreeBusyInfosFrom: startDate to: endDate];
|
||||
}
|
||||
|
||||
// No freebusy information found
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) startDate
|
||||
to: (NSCalendarDate *) endDate
|
||||
{
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
/* resources handling */
|
||||
NSString *kindField;
|
||||
NSString *multipleBookingsField;
|
||||
|
||||
NSString *MSExchangeHostname;
|
||||
}
|
||||
|
||||
- (void) setBindDN: (NSString *) newBindDN
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* LDAPSource.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2011 Inverse inc.
|
||||
* Copyright (C) 2007-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
@ -124,6 +124,8 @@ static NSArray *commonSearchFields;
|
|||
@"serialnumber",
|
||||
@"calfburl",
|
||||
@"proxyaddresses",
|
||||
// MS Exchange
|
||||
@"msExchHomeServerName",
|
||||
nil];
|
||||
[commonSearchFields retain];
|
||||
}
|
||||
|
@ -181,6 +183,8 @@ static NSArray *commonSearchFields;
|
|||
kindField = nil;
|
||||
multipleBookingsField = nil;
|
||||
|
||||
MSExchangeHostname = nil;
|
||||
|
||||
_dnCache = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
|
@ -216,6 +220,7 @@ static NSArray *commonSearchFields;
|
|||
[_dnCache release];
|
||||
[kindField release];
|
||||
[multipleBookingsField release];
|
||||
[MSExchangeHostname release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -249,7 +254,7 @@ static NSArray *commonSearchFields;
|
|||
IMAPLoginField: [udSource objectForKey: @"IMAPLoginFieldName"]
|
||||
bindFields: [udSource objectForKey: @"bindFields"]
|
||||
kindField: [udSource objectForKey: @"KindFieldName"]
|
||||
andMultipleBookingsField: [udSource objectForKey: @"MultipleBookingsFieldName"]];
|
||||
andMultipleBookingsField: [udSource objectForKey: @"MultipleBookingsFieldName"]];
|
||||
|
||||
if ([sourceDomain length])
|
||||
{
|
||||
|
@ -286,6 +291,8 @@ static NSArray *commonSearchFields;
|
|||
|
||||
if ([udSource objectForKey: @"passwordPolicy"])
|
||||
passwordPolicy = [[udSource objectForKey: @"passwordPolicy"] boolValue];
|
||||
|
||||
ASSIGN(MSExchangeHostname, [udSource objectForKey: @"MSExchangeHostname"]);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -297,11 +304,21 @@ static NSArray *commonSearchFields;
|
|||
ASSIGN(bindDN, theDN);
|
||||
}
|
||||
|
||||
- (NSString *) bindDN
|
||||
{
|
||||
return bindDN;
|
||||
}
|
||||
|
||||
- (void) setBindPassword: (NSString *) thePassword
|
||||
{
|
||||
ASSIGN (password, thePassword);
|
||||
}
|
||||
|
||||
- (NSString *) bindPassword
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
- (BOOL) bindAsCurrentUser
|
||||
{
|
||||
return _bindAsCurrentUser;
|
||||
|
@ -888,6 +905,7 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField
|
|||
id o;
|
||||
|
||||
contactEntry = [NSMutableDictionary dictionary];
|
||||
[contactEntry setObject: self forKey: @"source"];
|
||||
[contactEntry setObject: [ldapEntry dn] forKey: @"dn"];
|
||||
attributes = [[self _searchAttributes] objectEnumerator];
|
||||
|
||||
|
@ -1225,4 +1243,9 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField
|
|||
return baseDN;
|
||||
}
|
||||
|
||||
- (NSString *) MSExchangeHostname
|
||||
{
|
||||
return MSExchangeHostname;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoSource.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009-2010 Inverse inc.
|
||||
* Copyright (C) 2009-2012 Inverse inc.
|
||||
*
|
||||
* Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
*
|
||||
|
@ -63,13 +63,16 @@
|
|||
@protocol SOGoDNSource <SOGoSource>
|
||||
|
||||
- (void) setBindDN: (NSString *) theDN;
|
||||
- (NSString *) bindDN;
|
||||
- (void) setBindPassword: (NSString *) thePassword;
|
||||
- (NSString *) bindPassword;
|
||||
- (BOOL) bindAsCurrentUser;
|
||||
|
||||
- (NSString *) lookupLoginByDN: (NSString *) theDN;
|
||||
- (NSString *) lookupDNByLogin: (NSString *) theLogin;
|
||||
|
||||
- (NSString *) baseDN;
|
||||
- (NSString *) MSExchangeHostname;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
SOGoUserFolder *homeFolder;
|
||||
NSString *currentPassword;
|
||||
NSString *loginInDomain;
|
||||
NSString *language;
|
||||
//NSString *language;
|
||||
NSArray *allEmails;
|
||||
NSMutableArray *mailAccounts;
|
||||
NSString *cn;
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
[currentPassword release];
|
||||
[cn release];
|
||||
[loginInDomain release];
|
||||
[language release];
|
||||
//[language release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
|
@ -91,15 +91,16 @@
|
|||
return sharedUserManager;
|
||||
}
|
||||
|
||||
- (void) _registerSource: (NSDictionary *) udSource
|
||||
- (BOOL) _registerSource: (NSDictionary *) udSource
|
||||
inDomain: (NSString *) domain
|
||||
{
|
||||
NSString *sourceID, *value, *type;
|
||||
NSMutableDictionary *metadata;
|
||||
NSObject <SOGoSource> *sogoSource;
|
||||
BOOL isAddressBook;
|
||||
BOOL isAddressBook, result;
|
||||
Class c;
|
||||
|
||||
result = NO;
|
||||
sourceID = [udSource objectForKey: @"id"];
|
||||
if ([sourceID length] > 0)
|
||||
{
|
||||
|
@ -147,17 +148,20 @@
|
|||
[metadata setObject: value forKey: @"SearchFieldNames"];
|
||||
|
||||
[_sourcesMetadata setObject: metadata forKey: sourceID];
|
||||
result = YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"attempted to register a contact/user source"
|
||||
@" without id (skipped)"];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (int) _registerSourcesInDomain: (NSString *) domain
|
||||
{
|
||||
NSArray *userSources;
|
||||
unsigned int count, max;
|
||||
unsigned int count, max, total;
|
||||
SOGoDomainDefaults *dd;
|
||||
|
||||
if (domain)
|
||||
|
@ -167,11 +171,13 @@
|
|||
|
||||
userSources = [dd userSources];
|
||||
max = [userSources count];
|
||||
total = 0;
|
||||
for (count = 0; count < max; count++)
|
||||
[self _registerSource: [userSources objectAtIndex: count]
|
||||
inDomain: domain];
|
||||
if ([self _registerSource: [userSources objectAtIndex: count]
|
||||
inDomain: domain])
|
||||
total++;
|
||||
|
||||
return max;
|
||||
return total;
|
||||
}
|
||||
|
||||
- (void) _prepareSources
|
||||
|
@ -634,8 +640,7 @@
|
|||
if ([userEntry objectForKey: @"numberOfSimultaneousBookings"])
|
||||
[currentUser setObject: [userEntry objectForKey: @"numberOfSimultaneousBookings"]
|
||||
forKey: @"numberOfSimultaneousBookings"];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cn)
|
||||
|
@ -824,8 +829,9 @@
|
|||
{
|
||||
returnContact = [NSMutableDictionary dictionary];
|
||||
[returnContact setObject: uid forKey: @"c_uid"];
|
||||
[compactContacts setObject: returnContact forKey: uid];
|
||||
}
|
||||
[returnContact setObject: [userEntry objectForKey: @"source"] forKey: @"source"];
|
||||
[compactContacts setObject: returnContact forKey: uid];
|
||||
}
|
||||
if (![[returnContact objectForKey: @"c_name"] length])
|
||||
[returnContact setObject: [userEntry objectForKey: @"c_name"]
|
||||
forKey: @"c_name"];
|
||||
|
|
|
@ -158,6 +158,7 @@
|
|||
- (NSString *) _freeBusyFromStartDate: (NSCalendarDate *) startDate
|
||||
toEndDate: (NSCalendarDate *) endDate
|
||||
forFreeBusy: (SOGoFreeBusyObject *) fb
|
||||
andUser: (NSString *) user
|
||||
{
|
||||
NSMutableArray *freeBusy;
|
||||
unsigned int *freeBusyItems;
|
||||
|
@ -169,7 +170,7 @@
|
|||
|
||||
freeBusyItems = NSZoneCalloc (NULL, intervals, sizeof (int));
|
||||
[self _fillFreeBusyItems: freeBusyItems count: intervals
|
||||
withRecords: [fb fetchFreeBusyInfosFrom: startDate to: endDate]
|
||||
withRecords: [fb fetchFreeBusyInfosFrom: startDate to: endDate forUser: user]
|
||||
fromStartDate: startDate toEndDate: endDate];
|
||||
|
||||
freeBusy = [NSMutableArray arrayWithCapacity: intervals];
|
||||
|
@ -184,15 +185,16 @@
|
|||
- (id <WOActionResults>) readFreeBusyAction
|
||||
{
|
||||
WOResponse *response;
|
||||
SOGoFreeBusyObject *co;
|
||||
SOGoFreeBusyObject *freebusy;
|
||||
NSCalendarDate *startDate, *endDate;
|
||||
NSString *queryDay;
|
||||
NSString *queryDay, *uid;
|
||||
NSTimeZone *uTZ;
|
||||
SOGoUser *user;
|
||||
|
||||
user = [context activeUser];
|
||||
uTZ = [[user userDefaults] timeZone];
|
||||
|
||||
uid = [self queryParameterForKey: @"uid"];
|
||||
queryDay = [self queryParameterForKey: @"sday"];
|
||||
if ([queryDay length] == 8)
|
||||
{
|
||||
|
@ -211,13 +213,13 @@
|
|||
andString: @"Start date is later than end date."];
|
||||
else
|
||||
{
|
||||
co = [self clientObject];
|
||||
freebusy = [self clientObject];
|
||||
response
|
||||
= [self responseWithStatus: 200
|
||||
andString: [self
|
||||
_freeBusyFromStartDate: startDate
|
||||
toEndDate: endDate
|
||||
forFreeBusy: co]];
|
||||
andString: [self _freeBusyFromStartDate: startDate
|
||||
toEndDate: endDate
|
||||
forFreeBusy: freebusy
|
||||
andUser: uid]];
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -219,7 +219,7 @@ function performSearchCallback(http) {
|
|||
list.appendChild(node);
|
||||
node.address = completeEmail;
|
||||
// log("node.address: " + node.address);
|
||||
node.uid = contact["c_uid"];
|
||||
node.uid = (contact["isMSExchange"]? UserLogin + ":" : "") + contact["c_uid"];
|
||||
node.isList = isList;
|
||||
if (isList) {
|
||||
node.cname = contact["c_name"];
|
||||
|
@ -272,7 +272,7 @@ function performSearchCallback(http) {
|
|||
if (data.contacts.length == 1) {
|
||||
// Single result
|
||||
var contact = data.contacts[0];
|
||||
input.uid = contact["c_uid"];
|
||||
input.uid = (contact["isMSExchange"]? UserLogin + ":" : "") + contact["c_uid"];
|
||||
var isList = (contact["c_component"] &&
|
||||
contact["c_component"] == "vlist");
|
||||
if (isList) {
|
||||
|
@ -997,10 +997,18 @@ freeBusyRequest.prototype = {
|
|||
},
|
||||
|
||||
_performAjaxRequest: function fBR__performAjaxRequest(rqStart, rqEnd) {
|
||||
var urlstr = (UserFolderURL + "../" + this.mUid
|
||||
+ "/freebusy.ifb/ajaxRead?"
|
||||
+ "sday=" + rqStart.getDayString()
|
||||
+ "&eday=" + rqEnd.getDayString());
|
||||
var urlstr = UserFolderURL + "../";
|
||||
var uids = this.mUid.split(":");
|
||||
if (uids.length > 1)
|
||||
urlstr += (uids[0]
|
||||
+ "/freebusy.ifb/ajaxRead?"
|
||||
+ "uid=" + uids[1]
|
||||
+ "&");
|
||||
else
|
||||
urlstr += (this.mUid
|
||||
+ "/freebusy.ifb/ajaxRead?");
|
||||
urlstr += ("sday=" + rqStart.getDayString()
|
||||
+ "&eday=" + rqEnd.getDayString());
|
||||
|
||||
var thisRequest = this;
|
||||
var callback = function fBR__performAjaxRequest_cb(http) {
|
||||
|
|
Loading…
Reference in New Issue