Monotone-Parent: 2fdf0ead0781ef2362dd389811d5db44ca4cc84a

Monotone-Revision: c91eef7edcfd08d414664c25a590b6268a7e58e2

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2009-11-29T04:19:32
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2009-11-29 04:19:32 +00:00
parent 3821d1aa7f
commit b79a7e5a00
129 changed files with 4402 additions and 3316 deletions
+46
View File
@@ -1,3 +1,49 @@
2009-11-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/PreferencesUI/UIxPreferences.m (-): "hours" is now a static
variable, rather than an ivar.
* UI/MainUI/SOGoRootPage.m (+initialized): the supportedLanguages
are not available from the SOGoSystemDefaults
(SOGoDefaults.plist).
* UI/MailerUI/UIxMailView.m (+initialize): we never used
"SOGoDontUseETagsForMailViewer".
* UI/MailerUI/UIxMailEditor.m (+initialize): we never used
"SOGoShowInternetMarker" and "SOGoInternetMailHeaders".
* SoObjects/Mailer/SOGoDraftObject.m (+initialize):
"TextPlainType" was never used.
* SoObjects/SOGo/SOGoSystemDefaults.m: new class module handling
the getting of system (or "application") defaults, as well as
default values for users and domains.
* SoObjects/SOGo/SOGoDomainDefaults.m: new class module handling
the getting of domain defaults, as well as default values for for
users belonging to the corresponding domain.
* SoObjects/SOGo/SOGoUserDefaults.m: new class module handling
the setting and getting of user defaults.
* SoObjects/SOGo/SOGoLDAPDefaults.h: new protocol module for the
handling of "recursive" ldap defaults.
* SoObjects/SOGo/SOGoDefaultsSource.m: new module class acting as
a proxy between NSDictionary, NSUserDefaults and SOGoUserProfile,
enabling the possibility of hierarchy and fallbacks.
* SoObjects/SOGo/SOGoUserProfile.m: new name for SOGoUserDefaults.
(-arrayForKey:, -stringForKey:, -dataForKey:, -boolForKey:)
(-floatForKey:): removed obsolete methods (as well as their setter
counterparts).
* SoObjects/SOGo/SOGoSQLUserProfile.m: new class module for
handling the SQL backend of the SOGoUserProfile.
* UI/SOGoUI/WOContext+UIx.m: removed obsolete class.
2009-11-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/SOGo/SOGoUserDefaults.m (-fetchJSONProfileFromDB): the
+31 -56
View File
@@ -27,7 +27,6 @@
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSRunLoop.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLContentStore/GCSChannelManager.h>
@@ -45,71 +44,61 @@
#import <WEExtensions/WEResourceManager.h>
#import <SoObjects/SOGo/SOGoCache.h>
#import <SoObjects/SOGo/SOGoDAVAuthenticator.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoProxyAuthenticator.h>
#import <SoObjects/SOGo/SOGoUserFolder.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoWebAuthenticator.h>
#import <SoObjects/SOGo/WORequest+SOGo.h>
#import <SOGo/SOGoCache.h>
#import <SOGo/SOGoDAVAuthenticator.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoProxyAuthenticator.h>
#import <SOGo/SOGoUserFolder.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoStartupLogger.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoWebAuthenticator.h>
#import <SOGo/WORequest+SOGo.h>
#import "build.h"
#import "SOGoProductLoader.h"
#import "NSException+Stacktrace.h"
#import "SOGo.h"
#import "SOGoStartupLogger.h"
@implementation SOGo
static unsigned int vMemSizeLimit = 0;
static BOOL doCrashOnSessionCreate = NO;
static BOOL hasCheckedTables = NO;
static BOOL debugRequests = NO;
static BOOL useRelativeURLs = NO;
static unsigned int vMemSizeLimit;
static BOOL doCrashOnSessionCreate;
static BOOL hasCheckedTables;
static BOOL debugRequests;
static BOOL useRelativeURLs;
static BOOL trustProxyAuthentication;
#ifdef GNUSTEP_BASE_LIBRARY
static BOOL debugLeaks = NO;
static BOOL debugLeaks;
#endif
+ (void) initialize
{
NSUserDefaults *ud;
SOGoSystemDefaults *defaults;
SoClassSecurityInfo *sInfo;
NSArray *basicRoles;
SOGoStartupLogger *logger;
id tmp;
logger = [SOGoStartupLogger sharedLogger];
[logger logWithFormat: @"starting SOGo (build %@)", SOGoBuildDate];
ud = [NSUserDefaults standardUserDefaults];
if ([[ud persistentDomainForName: @"sogod"] count] == 0)
[logger warnWithFormat: @"No configuration found."
@" SOGo will not work properly."];
doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"];
debugRequests = [ud boolForKey: @"SOGoDebugRequests"];
defaults = [SOGoSystemDefaults sharedSystemDefaults];
doCrashOnSessionCreate = [defaults crashOnSessionCreate];
debugRequests = [defaults debugRequests];
#ifdef GNUSTEP_BASE_LIBRARY
debugLeaks = [ud boolForKey: @"SOGoDebugLeaks"];
debugLeaks = [defaults debugLeaks];
if (debugLeaks)
[logger logWithFormat: @"activating leak debugging"];
#endif
/* vMem size check - default is 384MB */
tmp = [ud objectForKey: @"SxVMemLimit"];
vMemSizeLimit = ((tmp != nil) ? [tmp intValue] : 384);
vMemSizeLimit = [defaults vmemLimit];
if (vMemSizeLimit > 0)
[logger logWithFormat: @"vmem size check enabled: shutting down app when "
@"vmem > %d MB", vMemSizeLimit];
#if LIB_FOUNDATION_LIBRARY
if ([ud boolForKey:@"SOGoEnableDoubleReleaseCheck"])
[NSAutoreleasePool enableDoubleReleaseCheck: YES];
#endif
@"vmem > %d MB", vMemSizeLimit];
/* SoClass security declarations */
sInfo = [self soClassSecurityInfo];
/* require View permission to access the root (bound to authenticated ...) */
@@ -125,8 +114,8 @@ static BOOL debugLeaks = NO;
[sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_View];
[sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
trustProxyAuthentication = [ud boolForKey: @"SOGoTrustProxyAuthentication"];
useRelativeURLs = [ud boolForKey: @"WOUseRelativeURLs"];
trustProxyAuthentication = [defaults trustProxyAuthentication];
useRelativeURLs = [defaults useRelativeURLs];
}
- (id) init
@@ -222,30 +211,17 @@ static BOOL debugLeaks = NO;
NSString *urlStrings[] = {@"SOGoProfileURL", @"OCSFolderInfoURL", nil};
NSString **urlString;
NSString *value;
NSUserDefaults *ud;
SOGoSystemDefaults *defaults;
BOOL ok;
ud = [NSUserDefaults standardUserDefaults];
defaults = [SOGoSystemDefaults sharedSystemDefaults];
ok = YES;
cm = [GCSChannelManager defaultChannelManager];
urlString = urlStrings;
while (ok && *urlString)
{
value = [ud stringForKey: *urlString];
if (!value & [*urlString isEqualToString: @"SOGoProfileURL"])
{
value = [ud stringForKey: @"AgenorProfileURL"];
if (value)
{
[ud setObject: value forKey: *urlString];
[ud removeObjectForKey: @"AgenorProfileURL"];
[ud synchronize];
[self warnWithFormat: @"the user defaults key 'AgenorProfileURL'"
@" was renamed to 'SOGoProfileURL'"];
}
}
value = [defaults stringForKey: *urlString];
if (value)
{
[self _checkTableWithCM: cm tableURL: value andType: *urlString];
@@ -309,9 +285,8 @@ static BOOL debugLeaks = NO;
user = [SOGoUser userWithLogin: _key roles: nil];
if (user)
userFolder = [$(@"SOGoUserFolder")
objectWithName: _key
inContainer: self];
userFolder = [$(@"SOGoUserFolder") objectWithName: _key
inContainer: self];
else
userFolder = nil;
+11 -83
View File
@@ -1,5 +1,6 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2006-2009 Inverse inc.
This file is part of OpenGroupware.org.
@@ -19,111 +20,38 @@
02111-1307, USA.
*/
#import <dlfcn.h>
#import <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/SoApplication.h>
#if defined(LDAP_CONFIG)
#import <SOGo/SOGoLDAPUserDefaults.h>
#endif
#import "SOGoStartupLogger.h"
typedef void (*NSUserDefaultsInitFunction) ();
#define DIR_SEP "/"
static void
BootstrapNSUserDefaults ()
{
char *filename;
NSUserDefaultsInitFunction SOGoNSUserDefaultsBootstrap;
void *handle;
filename = SOGO_LIBDIR DIR_SEP "libSOGoNSUserDefaults.so.1";
handle = dlopen (filename, RTLD_NOW | RTLD_GLOBAL);
if (handle)
{
SOGoNSUserDefaultsBootstrap = dlsym (handle,
"SOGoNSUserDefaultsBootstrap");
if (SOGoNSUserDefaultsBootstrap)
SOGoNSUserDefaultsBootstrap ();
}
}
static void
prepareUserDefaults (NSUserDefaults *ud)
{
NSString *redirectURL;
NSDictionary *domain;
SOGoStartupLogger *logger;
logger = [SOGoStartupLogger sharedLogger];
domain = [ud persistentDomainForName: @"sogod"];
if (![domain count])
{
domain = [ud persistentDomainForName: @"sogod-0.9"];
if ([domain count])
{
[logger logWithFormat: @"migrating user defaults from sogod-0.9"];
[ud setPersistentDomain: domain forName: @"sogod"];
[ud removePersistentDomainForName: @"sogod-0.9"];
[ud synchronize];
}
}
redirectURL = [ud stringForKey: @"WOApplicationRedirectURL"];
if (redirectURL)
{
[logger warnWithFormat:
@"Using obsolete 'WOApplicationRedirectURL' user default."];
[logger warnWithFormat:
@" Please configure the use of the x-webobjects-XXX headers"
@" with your webserver (see sample files)."];
if ([redirectURL hasSuffix: @"/"])
[ud setObject: [redirectURL substringToIndex: [redirectURL length] - 1]
forKey: @"WOApplicationRedirectURL"];
}
[ud setBool: YES forKey: @"WOMessageUseUTF8"];
[ud setBool: YES forKey: @"WOParsersUseUTF8"];
[ud setBool: YES forKey: @"NGUseUTF8AsURLEncoding"];
}
#import <SOGo/SOGoSystemDefaults.h>
int
main (int argc, char **argv, char **env)
{
NSString *tzName;
NSUserDefaults *ud;
NSAutoreleasePool *pool;
SOGoSystemDefaults *sd;
int rc;
pool = [NSAutoreleasePool new];
BootstrapNSUserDefaults ();
rc = -1;
if (getuid() > 0)
{
ud = [NSUserDefaults standardUserDefaults];
prepareUserDefaults (ud);
rc = 0;
tzName = [ud stringForKey: @"SOGoServerTimeZone"];
if (!tzName)
tzName = @"UTC";
[NSTimeZone setDefaultTimeZone:
[NSTimeZone timeZoneWithName: tzName]];
sd = [SOGoSystemDefaults sharedSystemDefaults];
[NSTimeZone setDefaultTimeZone: [sd timeZone]];
WOWatchDogApplicationMain (@"SOGo", argc, (void *) argv);
}
else
NSLog (@"Don't run SOGo as root!");
{
rc = -1;
NSLog (@"Don't run SOGo as root!");
}
[pool release];
-40
View File
@@ -46,11 +46,6 @@
(eg missing release due to an exception)
*/
#if defined(THREADSAFE)
static NSLock *channelLock;
static NSLock *adaptorLock;
#endif
@interface GCSChannelHandle : NSObject
{
@public
@@ -89,11 +84,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
[[ud objectForKey: @"GCSChannelCollectionTimer"] intValue];
if (ChannelCollectionTimer < 1)
ChannelCollectionTimer = 5*60;
#if defined(THREADSAFE)
channelLock = [NSLock new];
adaptorLock = [NSLock new];
#endif
}
+ (NSString *) adaptorNameForURLScheme: (NSString *) _scheme
@@ -106,14 +96,8 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
{
static GCSChannelManager *cm = nil;
#if defined(THREADSAFE)
[channelLock lock];
#endif
if (!cm)
cm = [self new];
#if defined(THREADSAFE)
[channelLock unlock];
#endif
return cm;
}
@@ -202,9 +186,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
{
if ((key = [self databaseKeyForURL: _url]))
{
#if defined(THREADSAFE)
[adaptorLock lock];
#endif
adaptor = [urlToAdaptor objectForKey: key];
if (adaptor)
[self debugWithFormat: @"using cached adaptor: %@", adaptor];
@@ -236,9 +217,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
[urlToAdaptor setObject: adaptor forKey: key];
}
#if defined(THREADSAFE)
[adaptorLock unlock];
#endif
}
}
@@ -319,9 +297,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
/* look for cached handles */
#if defined(THREADSAFE)
[channelLock lock];
#endif
handle = [self findAvailChannelHandleForURL: _url];
if (handle)
{
@@ -369,9 +344,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
}
}
}
#if defined(THREADSAFE)
[channelLock unlock];
#endif
return channel;
}
@@ -387,9 +359,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
GCSChannelHandle *handle;
BOOL keepOpen;
#if defined(THREADSAFE)
[channelLock lock];
#endif
handle = [self findBusyChannelHandleForChannel: _channel];
if (handle)
{
@@ -430,9 +399,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
[_channel release];
}
#if defined(THREADSAFE)
[channelLock unlock];
#endif
}
/* checking for tables */
@@ -481,9 +447,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
unsigned i, count;
GCSChannelHandle *handle;
#if defined(THREADSAFE)
[channelLock lock];
#endif
count = [availableChannels count];
if (count)
{
@@ -518,9 +481,6 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
[handlesToRemove release];
}
#if defined(THREADSAFE)
[channelLock unlock];
#endif
}
/* debugging */
-13
View File
@@ -75,10 +75,6 @@ static NSString *GCSGenericFolderTypeName = @"Container";
static const char *GCSPathColumnPattern = "c_path%i";
static NSCharacterSet *asciiAlphaNumericCS = nil;
#if defined(THREADSAFE)
static NSLock *lock;
#endif
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
@@ -91,9 +87,6 @@ static NSLock *lock;
debugOn = [ud boolForKey: @"GCSFolderManagerDebugEnabled"];
debugSQLGen = [ud boolForKey: @"GCSFolderManagerSQLDebugEnabled"];
emptyArray = [[NSArray alloc] init];
#if defined(THREADSAFE)
lock = [NSLock new];
#endif
if (!asciiAlphaNumericCS)
{
asciiAlphaNumericCS
@@ -109,9 +102,6 @@ static NSLock *lock;
NSString *s;
NSURL *url;
#if defined(THREADSAFE)
[lock lock];
#endif
if (!fm)
{
s = [[NSUserDefaults standardUserDefaults] stringForKey:@"OCSFolderInfoURL"];
@@ -133,9 +123,6 @@ static NSLock *lock;
if (debugOn)
[self debugWithFormat:@"Note: setup default manager at: %@", url];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
return fm;
}
@@ -56,6 +56,9 @@
NSMutableDictionary *uidToFilename;
NSMutableDictionary *aclMatrix;
NSMutableArray *stripFields;
int davCalendarStartTimeLimit;
int davTimeLimitSeconds;
int davTimeHalfLimitSeconds;
BOOL userCanAccessObjectsClassifiedAs[iCalAccessClassCount];
}
+32 -58
View File
@@ -25,7 +25,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/NSException+HTTP.h>
@@ -34,7 +33,6 @@
#import <NGObjWeb/WOMessage.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
#import <NGExtensions/NGLoggerManager.h>
#import <NGExtensions/NSString+misc.h>
#import <GDLContentStore/GCSFolder.h>
#import <DOM/DOMElement.h>
@@ -55,14 +53,17 @@
#import <SOGo/DOMNode+SOGo.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSObject+DAV.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoCache.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserSettings.h>
#import <SOGo/SOGoUserFolder.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/SOGoWebDAVAclManager.h>
#import <SOGo/SOGoWebDAVValue.h>
#import <SOGo/WORequest+SOGo.h>
@@ -80,39 +81,17 @@
@implementation SOGoAppointmentFolder
static NGLogger *logger = nil;
static NSNumber *sharedYes = nil;
static int davCalendarStartTimeLimit, davTimeLimitSeconds,
davTimeHalfLimitSeconds;
+ (void) initialize
{
NGLoggerManager *lm;
static BOOL didInit = NO;
NSUserDefaults *ud;
if (!didInit)
{
didInit = YES;
[iCalEntityObject initializeSOGoExtensions];
NSAssert2([super version] == 0,
@"invalid superclass (%@) version %i !",
NSStringFromClass([self superclass]), [super version]);
lm = [NGLoggerManager defaultLoggerManager];
logger = [lm loggerForDefaultKey: @"SOGoAppointmentFolderDebugEnabled"];
sharedYes = [[NSNumber numberWithBool: YES] retain];
ud = [NSUserDefaults standardUserDefaults];
davCalendarStartTimeLimit
= [ud integerForKey: @"SOGoDAVCalendarStartTimeLimit"];
davTimeLimitSeconds = davCalendarStartTimeLimit * 86400;
/* 86400 / 2 = 43200. We hardcode that value in order to avoid
integer and float confusion. */
davTimeHalfLimitSeconds = davCalendarStartTimeLimit * 43200;
[iCalEntityObject initializeSOGoExtensions];
}
}
@@ -250,14 +229,26 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (id) initWithName: (NSString *) name
inContainer: (id) newContainer
{
SOGoUser *user;
if ((self = [super initWithName: name inContainer: newContainer]))
{
timeZone = [[context activeUser] timeZone];
user = [context activeUser];
timeZone = [[user userDefaults] timeZone];
aclMatrix = [NSMutableDictionary new];
stripFields = nil;
uidToFilename = nil;
memset (userCanAccessObjectsClassifiedAs, NO,
iCalAccessClassCount * sizeof (BOOL));
davCalendarStartTimeLimit
= [[user domainDefaults] davCalendarStartTimeLimit];
davTimeLimitSeconds = davCalendarStartTimeLimit * 86400;
/* 86400 / 2 = 43200. We hardcode that value in order to avoid
integer and float confusion. */
davTimeHalfLimitSeconds = davCalendarStartTimeLimit * 43200;
davTimeLimitSeconds = 0;
davTimeHalfLimitSeconds = 0;
}
return self;
@@ -288,9 +279,8 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (void) _setCalendarProperty: (id) theValue
forKey: (NSString *) theKey
{
NSUserDefaults *settings;
NSMutableDictionary *calendarSettings;
NSMutableDictionary *values;
SOGoUserSettings *settings;
NSMutableDictionary *calendarSettings, *values;
settings = [[context activeUser] userSettings];
calendarSettings = [settings objectForKey: @"Calendar"];
@@ -325,7 +315,7 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (NSString *) calendarColor
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSDictionary *colors;
NSString *color;
@@ -351,7 +341,7 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (BOOL) showCalendarAlarms
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSDictionary *values;
id test;
BOOL show = YES;
@@ -378,7 +368,7 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (BOOL) showCalendarTasks
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSDictionary *values;
id test;
BOOL show = YES;
@@ -405,7 +395,7 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (NSString *) syncTag
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSDictionary *syncTags;
NSString *syncTag;
@@ -424,7 +414,7 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
if ([newSyncTag length])
{
// Check for duplicated tags
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSMutableDictionary *calendarSettings;
NSMutableDictionary *syncTags;
NSEnumerator *keysList;
@@ -463,7 +453,7 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
- (BOOL) synchronizeCalendar
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSDictionary *values;
id test;
BOOL synchronize = NO;
@@ -488,13 +478,6 @@ static int davCalendarStartTimeLimit, davTimeLimitSeconds,
forKey: @"FolderSynchronize"];
}
/* logging */
- (id) debugLogger
{
return logger;
}
/* selection */
- (NSArray *) calendarUIDs
@@ -1104,9 +1087,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[fields addObjectUniquely: @"c_enddate"];
[fields addObjectUniquely: @"c_isallday"];
if (logger)
[self debugWithFormat:@"should fetch (%@=>%@) ...", _startDate, endDate];
if (canCycle)
where = [NSString stringWithFormat: @"%@ %@ AND c_iscycle = 0",
baseWhere, dateSqlString];
@@ -1121,9 +1101,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
{
if (r)
records = [self fixupRecords: records];
if (logger)
[self debugWithFormat: @"fetched %i records: %@",
[records count], records];
ma = [NSMutableArray arrayWithArray: records];
}
else
@@ -1152,9 +1129,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return nil;
}
if (logger)
[self debugWithFormat:@"returning %i records", [ma count]];
currentLogin = [[context activeUser] login];
if (![currentLogin isEqualToString: owner] && !_includeProtectedInformation)
[self _fixupProtectedInformation: [ma objectEnumerator]
@@ -1685,8 +1659,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
NSString *ownerTimeZone;
ownerUser = [SOGoUser userWithLogin: [self ownerInContext: context]];
ownerTimeZone = [[ownerUser timeZone] name];
ownerTimeZone = [[ownerUser userDefaults] timeZoneName];
return [[iCalTimeZone timeZoneForName: ownerTimeZone] versitString];
}
@@ -2702,7 +2676,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
- (BOOL) create
{
BOOL rc;
NSUserDefaults *userSettings;
SOGoUserSettings *userSettings;
NSMutableDictionary *calendarSettings;
SOGoUser *ownerUser;
@@ -3077,7 +3051,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
- (BOOL) isActive
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSArray *inactiveFolders;
settings = [[context activeUser] userSettings];
@@ -278,7 +278,7 @@
- (NSArray *) webCalendarIds
{
NSUserDefaults *us;
SOGoUserSettings *us;
NSDictionary *tmp, *calendars;
NSArray *rc;
@@ -1384,7 +1384,8 @@
if ([event isParticipant: [[delegate email] rfc822Email]])
ex = [NSException exceptionWithHTTPStatus: 403
reason: @"delegate is a participant"];
else if ([SOGoGroup groupWithEmail: [[delegate email] rfc822Email]])
else if ([SOGoGroup groupWithEmail: [[delegate email] rfc822Email]
inDomain: [ownerUser domain]])
ex = [NSException exceptionWithHTTPStatus: 403
reason: @"delegate is a group"];
}
@@ -32,8 +32,9 @@
#import <NGCards/iCalEntityObject.h>
#import <NGCards/iCalPerson.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "iCalPerson+SOGo.h"
#import "SOGoAptMailICalReply.h"
@@ -146,10 +147,12 @@ static NSCharacterSet *wsSet = nil;
{
NSCalendarDate *date;
SOGoUser *user;
NSTimeZone *tz;
date = [apt startDate];
user = [[self context] activeUser];
[date setTimeZone: [user timeZone]];
tz = [[user userDefaults] timeZone];
[date setTimeZone: tz];
return date;
}
+3 -1
View File
@@ -92,11 +92,13 @@ static SOGoUserManager *um = nil;
SOGoDateFormatter *formatter;
NSCalendarDate *tzDate;
SOGoUser *currentUser;
SOGoUserDefaults *ud;
currentUser = [context activeUser];
ud = [currentUser userDefaults];
tzDate = [date copy];
[tzDate setTimeZone: [currentUser timeZone]];
[tzDate setTimeZone: [ud timeZone]];
[tzDate autorelease];
formatter = [currentUser dateFormatterInContext: context];
@@ -58,7 +58,6 @@
- (void) saveComponent: (iCalRepeatableEntityObject *) newObject;
/* mail notifications */
- (BOOL) sendEMailNotifications;
- (void) sendEMailUsingTemplateNamed: (NSString *) pageName
forObject: (iCalRepeatableEntityObject *) object
previousObject: (iCalRepeatableEntityObject *) previousObject
+29 -46
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoSecurityManager.h>
@@ -45,10 +44,12 @@
#import <SOGo/SOGoUserManager.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoMailer.h>
#import <SOGo/SOGoGroup.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/WORequest+SOGo.h>
#import <Appointments/SOGoAppointmentFolder.h>
@@ -61,28 +62,8 @@
#import "SOGoCalendarComponent.h"
#import "SOGoComponentOccurence.h"
static BOOL sendEMailNotifications = NO;
static BOOL sendEMailReceipts = NO;
@implementation SOGoCalendarComponent
+ (void) initialize
{
NSUserDefaults *ud;
static BOOL didInit = NO;
if (!didInit)
{
didInit = YES;
ud = [NSUserDefaults standardUserDefaults];
sendEMailNotifications
= [ud boolForKey: @"SOGoAppointmentSendEMailNotifications"];
sendEMailReceipts
= [ud boolForKey: @"SOGoAppointmentSendEMailReceipts"];
}
}
- (id) init
{
if ((self = [super init]))
@@ -419,19 +400,21 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
{
NSMutableArray *allAttendees;
NSEnumerator *enumerator;
NSString *organizerEmail;
NSString *organizerEmail, *domain;
iCalPerson *currentAttendee;
SOGoGroup *group;
BOOL doesIncludeGroup;
unsigned int i;
domain = [[context activeUser] domain];
organizerEmail = [[theEvent organizer] rfc822Email];
doesIncludeGroup = NO;
allAttendees = [NSMutableArray arrayWithArray: [theEvent attendees]];
enumerator = [[theEvent attendees] objectEnumerator];
while ((currentAttendee = [enumerator nextObject]))
{
group = [SOGoGroup groupWithEmail: [currentAttendee rfc822Email]];
group = [SOGoGroup groupWithEmail: [currentAttendee rfc822Email]
inDomain: domain];
if (group)
{
iCalPerson *person;
@@ -581,18 +564,15 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
: nil);
}
- (BOOL) sendEMailNotifications
{
return sendEMailNotifications;
}
- (NSTimeZone *) timeZoneForUser: (NSString *) email
{
NSString *uid;
SOGoUserDefaults *ud;
uid = [[SOGoUserManager sharedUserManager] getUIDForEmail: email];
ud = [[SOGoUser userWithLogin: uid] userDefaults];
return [[SOGoUser userWithLogin: uid] timeZone];
return [ud timeZone];
}
- (void) sendEMailUsingTemplateNamed: (NSString *) newPageName
@@ -613,15 +593,17 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
NGMimeBodyPart *bodyPart;
NGMimeMultipartBody *body;
SOGoUser *ownerUser;
SOGoDomainDefaults *dd;
if (sendEMailNotifications
&& [object isStillRelevant])
ownerUser = [SOGoUser userWithLogin: owner];
dd = [ownerUser domainDefaults];
if ([dd appointmentSendEMailNotifications] && [object isStillRelevant])
{
language = [[ownerUser userDefaults] language];
count = [attendees count];
if (count)
{
/* sender */
ownerUser = [SOGoUser userWithLogin: owner];
//currentUser = [context activeUser];
//shortSenderEmail = [[currentUser allEmails] objectAtIndex: 0];
// senderEmail = [NSString stringWithFormat: @"%@ <%@>",
@@ -651,7 +633,6 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
recipient = [attendee mailAddress];
email = [attendee rfc822Email];
language = [ownerUser language];
#warning this could be optimized in a class hierarchy common with the \
SOGoObject acl notification mechanism
/* create page name */
@@ -722,7 +703,7 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
[body release];
/* send the damn thing */
[[SOGoMailer sharedMailer]
[[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg
toRecipients: [NSArray arrayWithObject: email]
sender: shortSenderEmail];
@@ -747,24 +728,23 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
NGMimeBodyPart *bodyPart;
NGMimeMultipartBody *body;
NSData *bodyData;
SOGoUser *ownerUser;
SOGoDomainDefaults *dd;
if (sendEMailNotifications)
dd = [from domainDefaults];
if ([dd appointmentSendEMailNotifications])
{
/* get WOApplication instance */
app = [WOApplication application];
//ownerUser = [SOGoUser userWithLogin: owner];
ownerUser = from;
language = [ownerUser language];
language = [[from userDefaults] language];
/* create page name */
pageName
= [NSString stringWithFormat: @"SOGoAptMail%@ICalReply", language];
pageName = [NSString stringWithFormat: @"SOGoAptMail%@ICalReply",
language];
/* construct message content */
p = [app pageWithName: pageName inContext: context];
[p setApt: event];
attendee = [event findParticipant: ownerUser];
attendee = [event findParticipant: from];
[p setAttendee: attendee];
/* construct message */
@@ -816,7 +796,7 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
/* send the damn thing */
email = [recipient rfc822Email];
[[SOGoMailer sharedMailer]
[[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg
toRecipients: [NSArray arrayWithObject: email]
sender: [attendee rfc822Email]];
@@ -850,9 +830,12 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
NGMutableHashMap *headerMap;
NGMimeMessage *msg;
SOGoUser *currentUser;
SOGoDomainDefaults *dd;
NSDictionary *identity;
if (sendEMailReceipts && [attendees count])
currentUser = [context activeUser];
if ([[currentUser userDefaults] appointmentSendEMailReceipts]
&& [attendees count])
{
pageName = [NSString stringWithFormat: @"SOGoAptMail%@Receipt",
template];
@@ -861,7 +844,6 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
[page setApt: object];
[page setRecipients: attendees];
currentUser = [context activeUser];
identity = [currentUser primaryIdentity];
/* construct message */
@@ -884,7 +866,8 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence, NSStr
/* send the damn thing */
senderEmail = [identity objectForKey: @"email"];
[[SOGoMailer sharedMailer]
dd = [currentUser domainDefaults];
[[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg
toRecipients: [NSArray arrayWithObject: senderEmail]
sender: senderEmail];
+25 -30
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WOResponse.h>
@@ -32,8 +31,10 @@
#import <NGCards/iCalFreeBusy.h>
#import <NGCards/iCalPerson.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/SOGoPermissions.h>
#import "SOGoAppointmentFolder.h"
@@ -41,9 +42,6 @@
#import "SOGoFreeBusyObject.h"
static unsigned int freebusyRangeStart = 0;
static unsigned int freebusyRangeEnd = 0;
@interface SOGoFreeBusyObject (PrivateAPI)
- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
from: (NSCalendarDate *) _startDate
@@ -52,25 +50,6 @@ static unsigned int freebusyRangeEnd = 0;
@implementation SOGoFreeBusyObject
+ (void) initialize
{
NSArray *freebusyDateRange;
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
freebusyDateRange = [ud arrayForKey: @"SOGoFreeBusyDefaultInterval"];
if (freebusyDateRange && [freebusyDateRange count] > 1)
{
freebusyRangeStart = [[freebusyDateRange objectAtIndex: 0] unsignedIntValue];
freebusyRangeEnd = [[freebusyDateRange objectAtIndex: 1] unsignedIntValue];
}
else
{
freebusyRangeStart = 7;
freebusyRangeEnd = 7;
}
}
- (iCalPerson *) iCalPersonWithUID: (NSString *) uid
{
iCalPerson *person;
@@ -202,15 +181,31 @@ static unsigned int freebusyRangeEnd = 0;
- (NSString *) contentAsString
{
NSCalendarDate *today, *startDate, *endDate;
NSTimeZone *timeZone;
SOGoUserDefaults *ud;
SOGoDomainDefaults *dd;
NSArray *interval;
unsigned int start, end;
today = [[NSCalendarDate calendarDate] beginOfDay];
timeZone = [[context activeUser] timeZone];
[today setTimeZone: timeZone];
ud = [[context activeUser] userDefaults];
[today setTimeZone: [ud timeZone]];
startDate = [today dateByAddingYears: 0 months: 0 days: -freebusyRangeStart
dd = [[context activeUser] domainDefaults];
interval = [dd freeBusyDefaultInterval];
if ([interval count] > 1)
{
start = [[interval objectAtIndex: 0] unsignedIntValue];
end = [[interval objectAtIndex: 1] unsignedIntValue];
}
else
{
start = 7;
end = 7;
}
startDate = [today dateByAddingYears: 0 months: 0 days: -start
hours: 0 minutes: 0 seconds: 0];
endDate = [today dateByAddingYears: 0 months: 0 days: freebusyRangeEnd
endDate = [today dateByAddingYears: 0 months: 0 days: end
hours: 0 minutes: 0 seconds: 0];
return [self contentAsStringFrom: startDate to: endDate];
@@ -278,7 +273,7 @@ static unsigned int freebusyRangeEnd = 0;
- (id) GETAction: (id)_ctx
{
WOResponse *r;
NSData *contentData;
NSData *contentData;
contentData = [[self contentAsString]
dataUsingEncoding: NSUTF8StringEncoding];
-1
View File
@@ -20,7 +20,6 @@
*/
#import <Foundation/NSException.h>
#import <Foundation/NSUserDefaults.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSNull+misc.h>
@@ -78,7 +78,7 @@
- (NSException *) delete
{
NSException *error;
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSMutableDictionary *calSettings, *webCalendars;
NSString *name;
@@ -36,6 +36,7 @@
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserDefaults.h>
#import "iCalPerson+SOGo.h"
@@ -61,7 +62,8 @@ _computeAllDayOffset()
application = [WOApplication application];
user = [[application context] activeUser];
offset = utcOffset - [[user timeZone] secondsFromGMT];
tz = [[user userDefaults] timeZone];
offset = utcOffset - [tz secondsFromGMT];
return offset;
}
+6 -3
View File
@@ -32,7 +32,9 @@
#import <Foundation/NSString.h>
#import <Foundation/NSEnumerator.h>
#import <SoObjects/SOGo/SOGoUserManager.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserManager.h>
#import "SOGoContactGCSFolder.h"
#import "SOGoContactSourceFolder.h"
@@ -54,11 +56,12 @@
{
SOGoUserManager *um;
NSEnumerator *sourceIDs;
NSString *currentSourceID, *srcDisplayName;
NSString *currentSourceID, *srcDisplayName, *domain;
SOGoContactSourceFolder *currentFolder;
domain = [[context activeUser] domain];
um = [SOGoUserManager sharedUserManager];
sourceIDs = [[um addressBookSourceIDs] objectEnumerator];
sourceIDs = [[um addressBookSourceIDsInDomain: domain] objectEnumerator];
while ((currentSourceID = [sourceIDs nextObject]))
{
srcDisplayName = [um displayNameForSourceWithID: currentSourceID];
+7 -24
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGCards/NGVCard.h>
#import <NGCards/CardVersitRenderer.h>
@@ -32,22 +31,8 @@
#import "SOGoContactGCSEntry.h"
#import "SOGoContactLDIFEntry.h"
static NSString *sogoContactInfoAttribute = nil;
@implementation SOGoContactLDIFEntry
+ (void) initialize
{
NSUserDefaults *ud;
if (!sogoContactInfoAttribute)
{
ud = [NSUserDefaults standardUserDefaults];
ASSIGN (sogoContactInfoAttribute,
[ud stringForKey: @"SOGoLDAPContactInfoAttribute"]);
}
}
+ (SOGoContactLDIFEntry *) contactEntryWithName: (NSString *) newName
withLDIFEntry: (NSDictionary *) newEntry
inContainer: (id) newContainer
@@ -126,7 +111,7 @@ static NSString *sogoContactInfoAttribute = nil;
- (NGVCard *) vCard
{
NSString *info, *surname, *streetAddress, *location, *key, *region, *postalCode, *country, *org, *orgunit;
NSString *info, *surname, *streetAddress, *location, *region, *postalCode, *country, *org, *orgunit;
CardElement *element;
unsigned int count;
@@ -159,14 +144,12 @@ static NSString *sogoContactInfoAttribute = nil;
if (info)
[vcard setNickname: info];
/* If SOGoLDAPContactInfoAttribute is defined, we set as the NOTE value
in order for Thunderbird (or any other CardDAV client) to display it. */
if (sogoContactInfoAttribute)
key = [sogoContactInfoAttribute lowercaseString];
else
key = @"description";
info = [ldifEntry objectForKey: key];
if (info)
/* If "c_info" is defined, we set as the NOTE value in order for
Thunderbird (or any other CardDAV client) to display it. */
info = [ldifEntry objectForKey: @"c_info"];
if (![info length])
info = [ldifEntry objectForKey: @"description"];
if ([info length])
[vcard setNote: info];
info = [ldifEntry objectForKey: @"mail"];
+5 -11
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOApplication.h>
@@ -199,10 +198,8 @@
NSEnumerator *oldRecords;
NSDictionary *oldRecord;
NSMutableDictionary *newRecord;
NSString *data, *contactInfo;
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
NSString *data;
newRecords = [[NSMutableArray alloc] initWithCapacity: [records count]];
[newRecords autorelease];
@@ -257,12 +254,9 @@
if (data)
[newRecord setObject: data forKey: @"isGroup"];
contactInfo = [[ud stringForKey: @"SOGoLDAPContactInfoAttribute"] lowercaseString];
if ([contactInfo length] > 0) {
data = [oldRecord objectForKey: contactInfo];
if ([data length] > 0)
[newRecord setObject: data forKey: @"contactInfo"];
}
data = [oldRecord objectForKey: @"c_info"];
if ([data length] > 0)
[newRecord setObject: data forKey: @"contactInfo"];
[newRecords addObject: newRecord];
oldRecord = [oldRecords nextObject];
+32 -43
View File
@@ -26,7 +26,6 @@
#import <Foundation/NSKeyValueCoding.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/NSException+HTTP.h>
@@ -54,11 +53,13 @@
#import <NGMime/NGMimeHeaderFieldGenerator.h>
#import <NGMime/NGMimeHeaderFields.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/SOGo/SOGoMailer.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoMailer.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "NSData+Mail.h"
#import "NSString+Mail.h"
@@ -77,25 +78,13 @@ static NSString *headerKeys[] = {@"subject", @"to", @"cc", @"bcc",
@implementation SOGoDraftObject
static NGMimeType *TextPlainType = nil;
static NGMimeType *MultiMixedType = nil;
static NSString *userAgent = @"SOGoMail 1.0";
static BOOL draftDeleteDisabled = NO; // for debugging
static BOOL debugOn = NO;
static BOOL showTextAttachmentsInline = NO;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
/* Note: be aware of the charset issues before enabling this! */
showTextAttachmentsInline = [ud boolForKey: @"SOGoShowTextAttachmentsInline"];
if ((draftDeleteDisabled = [ud boolForKey: @"SOGoNoDraftDeleteAfterSend"]))
NSLog(@"WARNING: draft delete is disabled! (SOGoNoDraftDeleteAfterSend)");
TextPlainType = [[NGMimeType mimeType: @"text" subType: @"plain"] copy];
MultiMixedType = [[NGMimeType mimeType: @"multipart" subType: @"mixed"] copy];
MultiMixedType = [NGMimeType mimeType: @"multipart" subType: @"mixed"];
[MultiMixedType retain];
}
- (id) init
@@ -651,7 +640,7 @@ static BOOL showTextAttachmentsInline = NO;
- (void) fetchMailForForwarding: (SOGoMailObject *) sourceMail
{
NSDictionary *info, *attachment;
SOGoUser *currentUser;
SOGoUserDefaults *ud;
NSString *signature;
[sourceMail fetchCoreInfos];
@@ -667,8 +656,8 @@ static BOOL showTextAttachmentsInline = NO;
[self setSourceFlag: @"$Forwarded"];
/* attach message */
currentUser = [context activeUser];
if ([[currentUser messageForwarding] isEqualToString: @"inline"])
ud = [[context activeUser] userDefaults];
if ([[ud mailMessageForwarding] isEqualToString: @"inline"])
{
[self setText: [sourceMail contentForInlineForward]];
[self _fetchAttachments: [sourceMail fetchFileAttachmentKeys]
@@ -678,7 +667,7 @@ static BOOL showTextAttachmentsInline = NO;
{
// TODO: use subject for filename?
// error = [newDraft saveAttachment:content withName:@"forward.eml"];
signature = [currentUser signature];
signature = [ud mailSignature];
if ([signature length])
[self setText: [NSString stringWithFormat: @"\n-- \n%@", signature]];
attachment = [NSDictionary dictionaryWithObjectsAndKeys:
@@ -833,7 +822,7 @@ static BOOL showTextAttachmentsInline = NO;
*/
NGMutableHashMap *map;
NGMimeBodyPart *bodyPart;
NSUserDefaults *ud;
SOGoUserDefaults *ud;
ud = [[context activeUser] userDefaults];
@@ -845,8 +834,8 @@ static BOOL showTextAttachmentsInline = NO;
[map setObject: @"text/plain" forKey: @"content-type"];
if (text)
{
if ([[ud stringForKey: @"ComposeMessagesType"] isEqualToString: @"html"])
[map setObject: htmlContentTypeValue
if ([[ud mailComposeMessageType] isEqualToString: @"html"])
[map setObject: htmlContentTypeValue
forKey: @"content-type"];
else
[map setObject: contentTypeValue forKey: @"content-type"];
@@ -871,7 +860,7 @@ static BOOL showTextAttachmentsInline = NO;
- (NGMimeMessage *) mimeMessageForContentWithHeaderMap: (NGMutableHashMap *) map
{
NGMimeMessage *message;
NSUserDefaults *ud;
SOGoUserDefaults *ud;
// BOOL addSuffix;
id body;
@@ -883,7 +872,7 @@ static BOOL showTextAttachmentsInline = NO;
{
// if ([body isKindOfClass:[NSString class]])
/* Note: just 'utf8' is displayed wrong in Mail.app */
if ([[ud stringForKey: @"ComposeMessagesType"] isEqualToString: @"html"])
if ([[ud mailComposeMessageType] isEqualToString: @"html"])
[map setObject: htmlContentTypeValue
forKey: @"content-type"];
else
@@ -951,11 +940,15 @@ static BOOL showTextAttachmentsInline = NO;
NSString *type;
NSString *cdtype;
NSString *cd;
SOGoDomainDefaults *dd;
type = [self contentTypeForAttachmentWithName:_name];
if ([type hasPrefix: @"text/"])
cdtype = showTextAttachmentsInline ? @"inline" : @"attachment";
{
dd = [[context activeUser] domainDefaults];
cdtype = [dd mailAttachTextDocumentsInline] ? @"inline" : @"attachment";
}
else if ([type hasPrefix: @"image/"] || [type hasPrefix: @"message"])
cdtype = @"inline";
else
@@ -1366,7 +1359,8 @@ static BOOL showTextAttachmentsInline = NO;
SOGoMailFolder *sentFolder;
NSData *message;
NSURL *sourceIMAP4URL;
SOGoDomainDefaults *dd;
/* send mail */
sentFolder = [[self mailAccountFolder] sentFolderInContext: context];
if ([sentFolder isKindOfClass: [NSException class]])
@@ -1374,9 +1368,11 @@ static BOOL showTextAttachmentsInline = NO;
else
{
message = [self mimeMessageAsData];
error = [[SOGoMailer sharedMailer] sendMailData: message
toRecipients: [self allBareRecipients]
sender: [self sender]];
dd = [[context activeUser] domainDefaults];
error = [[SOGoMailer mailerWithDomainDefaults: dd]
sendMailData: message
toRecipients: [self allBareRecipients]
sender: [self sender]];
if (!error)
{
error = [sentFolder postData: message flags: @"seen"];
@@ -1390,7 +1386,7 @@ static BOOL showTextAttachmentsInline = NO;
sourceIMAP4URL = [NSURL URLWithString: sourceURL];
[imap4 addFlags: sourceFlag toURL: sourceIMAP4URL];
}
if (!draftDeleteDisabled)
if (![dd mailKeepDraftsAfterSend])
error = [self delete];
}
}
@@ -1441,11 +1437,4 @@ static BOOL showTextAttachmentsInline = NO;
return str;
}
/* debugging */
- (BOOL) isDebuggingEnabled
{
return debugOn;
}
@end /* SOGoDraftObject */
-20
View File
@@ -22,7 +22,6 @@
#import <Foundation/NSDate.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SoObjects/SOGo/SOGoUser.h>
@@ -31,29 +30,11 @@
#import "SOGoDraftsFolder.h"
static NSString *spoolFolder = nil;
static NSTimeInterval lastNew = 0;
static unsigned int newCount;
@implementation SOGoDraftsFolder
+ (void) initialize
{
NSUserDefaults *ud;
if (!spoolFolder)
{
ud = [NSUserDefaults standardUserDefaults];
spoolFolder = [ud stringForKey:@"SOGoMailSpoolPath"];
if (![spoolFolder length])
spoolFolder = @"/tmp/";
[spoolFolder retain];
NSLog(@"Note: using SOGo mail spool folder: %@", spoolFolder);
}
}
- (NSString *) generateNameForNewDraft
{
NSString *newName, *login;
@@ -102,5 +83,4 @@ static unsigned int newCount;
return YES;
}
@end
+10 -1
View File
@@ -41,6 +41,12 @@
#import "SOGoSentFolder.h"
#import "SOGoTrashFolder.h"
typedef enum {
undefined = -1,
rfc2086 = 0,
rfc4314
} SOGoIMAPAclStyle;
@interface SOGoMailAccount : SOGoMailBaseObject
{
NSString *accountName;
@@ -48,17 +54,20 @@
SOGoDraftsFolder *draftsFolder;
SOGoSentFolder *sentFolder;
SOGoTrashFolder *trashFolder;
SOGoIMAPAclStyle imapAclStyle;
}
- (void) setAccountName: (NSString *) newAccountName;
- (SOGoIMAPAclStyle) imapAclStyle;
- (BOOL) imapAclConformsToIMAPExt;
- (BOOL) supportsQuotas;
- (BOOL) updateFilters;
/* folder pathes */
- (NSArray *) allFolderPaths;
- (NSArray *) additionalRootFolderNames; /* stuff like filters and drafts */
- (BOOL) isInDraftsFolder;
/* shared accounts */
+116 -117
View File
@@ -21,9 +21,9 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoHTTPAuthenticator.h>
@@ -38,8 +38,11 @@
#import <NGImap4/NGImap4Context.h>
#import <NGImap4/NGSieveClient.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserSettings.h>
#import "SOGoDraftsFolder.h"
#import "SOGoMailFolder.h"
@@ -51,66 +54,9 @@
@implementation SOGoMailAccount
static NSArray *rootFolderNames = nil;
static NSString *inboxFolderName = @"INBOX";
static NSString *draftsFolderName = @"Drafts";
static NSString *sentFolderName = nil;
static NSString *trashFolderName = nil;
static NSString *sharedFolderName = @""; // TODO: add English default
static NSString *otherUsersFolderName = @""; // TODO: add English default
static NSString *sieveScriptName = @"sogo";
static BOOL defaultShowSubscribedFoldersOnly = NO;
// this is temporary, until we allow users to manage their own accounts
static NSString *fallbackIMAP4Server = nil;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *cfgDraftsFolderName;
sharedFolderName = [ud stringForKey:@"SOGoSharedFolderName"];
otherUsersFolderName = [ud stringForKey:@"SOGoOtherUsersFolderName"];
cfgDraftsFolderName = [ud stringForKey:@"SOGoDraftsFolderName"];
if (!sentFolderName)
{
sentFolderName = [ud stringForKey: @"SOGoSentFolderName"];
if (!sentFolderName)
sentFolderName = @"Sent";
[sentFolderName retain];
}
if (!trashFolderName)
{
trashFolderName = [ud stringForKey: @"SOGoTrashFolderName"];
if (!trashFolderName)
trashFolderName = @"Trash";
[trashFolderName retain];
}
if ([cfgDraftsFolderName length] > 0)
{
ASSIGN (draftsFolderName, cfgDraftsFolderName);
NSLog(@"Note: using drafts folder named: '%@'", draftsFolderName);
}
NSLog(@"Note: using shared-folders name: '%@'", sharedFolderName);
NSLog(@"Note: using other-users-folders name: '%@'", otherUsersFolderName);
rootFolderNames = [[NSArray alloc] initWithObjects:
draftsFolderName,
nil];
if (!fallbackIMAP4Server)
{
fallbackIMAP4Server = [ud stringForKey: @"SOGoFallbackIMAP4Server"];
if (fallbackIMAP4Server)
[fallbackIMAP4Server retain];
else
fallbackIMAP4Server = @"localhost";
}
defaultShowSubscribedFoldersOnly = [ud boolForKey: @"SOGoMailShowSubscribedFoldersOnly"];
}
- (id) init
{
if ((self = [super init]))
@@ -120,6 +66,7 @@ static NSString *fallbackIMAP4Server = nil;
sentFolder = nil;
trashFolder = nil;
accountName = nil;
imapAclStyle = undefined;
}
return self;
@@ -163,11 +110,6 @@ static NSString *fallbackIMAP4Server = nil;
/* listing the available folders */
- (NSArray *) additionalRootFolderNames
{
return rootFolderNames;
}
- (BOOL) isInDraftsFolder
{
return NO;
@@ -181,7 +123,8 @@ static NSString *fallbackIMAP4Server = nil;
folders = [NSMutableArray array];
imapFolders = [[self imap4Connection] subfoldersForURL: [self imap4URL]];
additionalFolders = [self additionalRootFolderNames];
additionalFolders
= [NSArray arrayWithObject: [self draftsFolderNameInContext: nil]];
if ([imapFolders count] > 0)
[folders addObjectsFromArray: imapFolders];
if ([additionalFolders count] > 0)
@@ -193,6 +136,31 @@ static NSString *fallbackIMAP4Server = nil;
return [folders stringsWithFormat: @"folder%@"];
}
- (SOGoIMAPAclStyle) imapAclStyle
{
SOGoDomainDefaults *dd;
if (imapAclStyle == undefined)
{
dd = [[context activeUser] domainDefaults];
if ([[dd imapAclStyle] isEqualToString: @"rfc2086"])
imapAclStyle = rfc2086;
else
imapAclStyle = rfc4314;
}
return imapAclStyle;
}
- (BOOL) imapAclConformsToIMAPExt
{
SOGoDomainDefaults *dd;
dd = [[context activeUser] domainDefaults];
return [dd imapAclConformsToIMAPExt];
}
- (BOOL) supportsQuotas
{
NGImap4Client *imapClient;
@@ -209,13 +177,14 @@ static NSString *fallbackIMAP4Server = nil;
NSMutableString *header, *script;
NGInternetSocketAddress *address;
NSDictionary *result, *values;
NSUserDefaults *ud;
SOGoUserDefaults *ud;
SOGoDomainDefaults *dd;
NGSieveClient *client;
NSString *v;
BOOL b;
if (![[NSUserDefaults standardUserDefaults] boolForKey: @"SOGoVacationEnabled"] &&
![[NSUserDefaults standardUserDefaults] boolForKey: @"SOGoForwardEnabled"])
dd = [[context activeUser] domainDefaults];
if (!([dd vacationEnabled] || [dd forwardEnabled]))
return YES;
ud = [[context activeUser] userDefaults];
@@ -227,7 +196,7 @@ static NSString *fallbackIMAP4Server = nil;
// Right now, we handle Sieve filters here and only for vacation
// and forwards. Traditional filters support (for fileinto, for
// example) will be added later.
values = [ud objectForKey: @"Vacation"];
values = [ud vacationOptions];
// We handle vacation messages.
// See http://ietfreport.isoc.org/idref/draft-ietf-sieve-vacation/
@@ -273,7 +242,7 @@ static NSString *fallbackIMAP4Server = nil;
// We handle mail forward
values = [ud objectForKey: @"Forward"];
values = [ud forwardOptions];
if (values && [[values objectForKey: @"enabled"] boolValue])
{
@@ -356,17 +325,11 @@ static NSString *fallbackIMAP4Server = nil;
{
NSMutableArray *folderPaths;
NSArray *rawFolders, *mainFolders;
NSUserDefaults *ud;
NSString *showSubscribedFoldersOnly;
SOGoUserDefaults *ud;
ud = [[context activeUser] userDefaults];
showSubscribedFoldersOnly = [ud stringForKey: @"showSubscribedFoldersOnly"];
if (showSubscribedFoldersOnly)
rawFolders = [[self imap4Connection] allFoldersForURL: [self imap4URL]
onlySubscribedFolders: [showSubscribedFoldersOnly boolValue]];
else
rawFolders = [[self imap4Connection] allFoldersForURL: [self imap4URL]
onlySubscribedFolders: defaultShowSubscribedFoldersOnly];
rawFolders = [[self imap4Connection] allFoldersForURL: [self imap4URL]
onlySubscribedFolders: [ud mailShowSubscribedFoldersOnly]];
mainFolders = [[NSArray arrayWithObjects:
[self inboxFolderNameInContext: context],
@@ -428,14 +391,8 @@ static NSString *fallbackIMAP4Server = nil;
escUsername
= [[username stringByEscapingURL] stringByReplacingString: @"@"
withString: @"%40"];
#if 1
// see comment about fallbackIMAP4Server above
hostString = [NSString stringWithFormat: @"%@@%@", escUsername,
[mailAccount objectForKey: @"serverName"]];
#else
hostString = [NSString stringWithFormat: @"%@@%@", escUsername,
fallbackIMAP4Server];
#endif
[mailAccount objectForKey: @"serverName"]];
}
else
hostString = @"localhost";
@@ -519,54 +476,88 @@ static NSString *fallbackIMAP4Server = nil;
return inboxFolderName;
}
- (BOOL) _migrateFolderWithPurpose: (NSString *) purpose
withName: (NSString *) folderName
{
SOGoUserDefaults *ud;
NSString *methodName;
SEL methodSel;
BOOL rc;
ud = [[context activeUser] userDefaults];
methodName = [NSString stringWithFormat: @"set%@FolderName:", purpose];
methodSel = NSSelectorFromString (methodName);
if ([ud respondsToSelector: methodSel])
{
[ud performSelector: methodSel withObject: folderName];
[ud synchronize];
rc = YES;
}
else
{
[self errorWithFormat: @"method '%@' not available with user defaults"@
@" object, folder migration fails", methodName];
rc = NO;
}
return rc;
}
- (NSString *) _userFolderNameWithPurpose: (NSString *) purpose
{
NSUserDefaults *ud;
SOGoUser *user;
SOGoUserSettings *us;
SOGoUserDefaults *ud;
NSMutableDictionary *mailSettings;
NSString *folderName;
NSString *folderName, *key, *methodName;
SEL methodSel;
folderName = nil;
ud = [[context activeUser] userSettings];
mailSettings = [ud objectForKey: @"Mail"];
user = [context activeUser];
/* migration part: */
us = [user userSettings];
mailSettings = [us objectForKey: @"Mail"];
if (mailSettings)
folderName
= [mailSettings objectForKey: [NSString stringWithFormat: @"%@Folder",
purpose]];
{
key = [NSString stringWithFormat: @"%@Folder", purpose];
folderName = [mailSettings objectForKey: key];
if ([folderName length]
&& [self _migrateFolderWithPurpose: purpose withName: folderName])
{
[mailSettings removeObjectForKey: key];
[us synchronize];
folderName = nil;
}
}
else
folderName = nil;
if (!folderName)
{
ud = [[context activeUser] userDefaults];
methodName = [NSString stringWithFormat: @"%@FolderName",
[purpose lowercaseString]];
methodSel = NSSelectorFromString (methodName);
folderName = [ud performSelector: methodSel];
}
return folderName;
}
- (NSString *) draftsFolderNameInContext: (id) _ctx
{
NSString *folderName;
folderName = [self _userFolderNameWithPurpose: @"Drafts"];
if (!folderName)
folderName = draftsFolderName;
return folderName;
return [self _userFolderNameWithPurpose: @"Drafts"];
}
- (NSString *) sentFolderNameInContext: (id)_ctx
{
NSString *folderName;
folderName = [self _userFolderNameWithPurpose: @"Sent"];
if (!folderName)
folderName = sentFolderName;
return folderName;
return [self _userFolderNameWithPurpose: @"Sent"];
}
- (NSString *) trashFolderNameInContext: (id)_ctx
{
NSString *folderName;
folderName = [self _userFolderNameWithPurpose: @"Trash"];
if (!folderName)
folderName = trashFolderName;
return folderName;
return [self _userFolderNameWithPurpose: @"Trash"];
}
- (id) folderWithTraversal: (NSString *) traversal
@@ -713,12 +704,20 @@ static NSString *fallbackIMAP4Server = nil;
- (NSString *) sharedFolderName
{
return sharedFolderName;
SOGoDomainDefaults *dd;
dd = [[context activeUser] domainDefaults];
return [dd sharedFolderName];
}
- (NSString *) otherUsersFolderName
{
return otherUsersFolderName;
SOGoDomainDefaults *dd;
dd = [[context activeUser] domainDefaults];
return [dd otherUsersFolderName];
}
@end /* SOGoMailAccount */
+11 -13
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoObject+SoDAV.h>
@@ -50,18 +49,17 @@ static BOOL debugOn = NO;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
if (![[ud objectForKey:@"SOGoMailDisableETag"] boolValue]) {
mailETag = [[NSString alloc] initWithFormat:@"\"imap4url_%d_%d_%03d\"",
UIX_MAILER_MAJOR_VERSION,
UIX_MAILER_MINOR_VERSION,
UIX_MAILER_SUBMINOR_VERSION];
NSLog(@"Note(SOGoMailBodyPart): using constant etag for mail parts: '%@'",
mailETag);
}
else
NSLog(@"Note(SOGoMailBodyPart): etag caching disabled!");
if (!mailETag)
{
/* The following disabled code should not be needed, except if we use
annotations (see davEntityTag below) */
// if (![[ud objectForKey: @"SOGoMailDisableETag"] boolValue]) {
mailETag = [[NSString alloc] initWithFormat:@"\"imap4url_%d_%d_%03d\"",
UIX_MAILER_MAJOR_VERSION,
UIX_MAILER_MINOR_VERSION,
UIX_MAILER_SUBMINOR_VERSION];
}
}
- (id) init
-8
View File
@@ -38,12 +38,6 @@
@class NGImap4MailboxInfo;
@class WOResponse;
typedef enum {
undefined = -1,
rfc2086 = 0,
rfc4314
} SOGoIMAPAclStyle;
@interface SOGoMailFolder : SOGoMailBaseObject
{
NSMutableArray *filenames;
@@ -51,8 +45,6 @@ typedef enum {
NSDictionary *mailboxACL;
}
+ (SOGoIMAPAclStyle) imapAclStyle;
- (NSString *) absoluteImap4Name;
/* messages */
+31 -91
View File
@@ -22,7 +22,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSTask.h>
#import <NGObjWeb/NSException+HTTP.h>
@@ -48,8 +47,11 @@
#import <SOGo/NSString+DAV.h>
#import <SOGo/NSArray+DAV.h>
#import <SOGo/NSObject+DAV.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserSettings.h>
#import <SOGo/WORequest+SOGo.h>
#import "EOQualifier+MailDAV.h"
@@ -62,14 +64,6 @@
static NSString *defaultUserID = @"anyone";
#warning this could be detected from the capabilities
static SOGoIMAPAclStyle aclStyle = undefined;
static BOOL aclUsernamesAreQuoted = NO;
/* http://www.tools.ietf.org/wg/imapext/draft-ietf-imapext-acl/ */
static BOOL aclConformsToIMAPExt = NO;
static NSString *spoolFolder = nil;
@interface NGImap4Connection (PrivateMethods)
- (NSString *) imap4FolderNameForURL: (NSURL *) url;
@@ -78,42 +72,6 @@ static NSString *spoolFolder = nil;
@implementation SOGoMailFolder
+ (void) initialize
{
NSUserDefaults *ud;
NSString *aclStyleStr;
if (aclStyle == undefined)
{
ud = [NSUserDefaults standardUserDefaults];
aclStyleStr = [ud stringForKey: @"SOGoIMAPAclStyle"];
if ([aclStyleStr isEqualToString: @"rfc2086"])
aclStyle = rfc2086;
else
aclStyle = rfc4314;
aclUsernamesAreQuoted
= [ud boolForKey: @"SOGoIMAPAclUsernamesAreQuoted"];
aclConformsToIMAPExt
= [ud boolForKey: @"SOGoIMAPAclConformsToIMAPExt"];
}
if (!spoolFolder)
{
spoolFolder = [ud stringForKey:@"SOGoMailSpoolPath"];
if (![spoolFolder length])
spoolFolder = @"/tmp/";
[spoolFolder retain];
NSLog(@"Note: using SOGo mail spool folder: %@", spoolFolder);
}
}
+ (SOGoIMAPAclStyle) imapAclStyle
{
return aclStyle;
}
- (void) _adjustOwner
{
SOGoMailAccount *mailAccount;
@@ -342,7 +300,7 @@ static NSString *spoolFolder = nil;
}
- (WOResponse *) archiveUIDs: (NSArray *) uids
inContext: (id) localContext
inContext: (id) localContext
{
NSException *error;
NSFileManager *fm;
@@ -357,20 +315,18 @@ static NSString *spoolFolder = nil;
#warning this method should be rewritten according to our coding styles
spoolPath = [self userSpoolFolderPath];
if ( ![self ensureSpoolFolderPath] ) {
if (![self ensureSpoolFolderPath]) {
[self errorWithFormat: @"spool directory '%@' doesn't exist", spoolPath];
error = [NSException exceptionWithHTTPStatus: 500
reason: @"spoolFolderPath doesn't exist"];
reason: @"spool directory does not exist"];
return (WOResponse *)error;
}
zipPath = [[NSUserDefaults standardUserDefaults] stringForKey: @"SOGoZipPath"];
if (![zipPath length])
zipPath = [NSString stringWithString: @"/usr/bin/zip"];
zipPath = [[SOGoSystemDefaults sharedSystemDefaults] zipPath];
fm = [NSFileManager defaultManager];
if ( ![fm fileExistsAtPath: zipPath] ) {
if (![fm fileExistsAtPath: zipPath]) {
error = [NSException exceptionWithHTTPStatus: 500
reason: @"zip not available"];
reason: @"zip not available"];
return (WOResponse *)error;
}
@@ -527,16 +483,16 @@ static NSString *spoolFolder = nil;
- (void) markForExpunge
{
NSUserDefaults *ud;
SOGoUserSettings *us;
NSMutableDictionary *mailSettings;
NSString *urlString;
ud = [[context activeUser] userSettings];
mailSettings = [ud objectForKey: @"Mail"];
us = [[context activeUser] userSettings];
mailSettings = [us objectForKey: @"Mail"];
if (!mailSettings)
{
mailSettings = [NSMutableDictionary dictionaryWithCapacity: 1];
[ud setObject: mailSettings forKey: @"Mail"];
[us setObject: mailSettings forKey: @"Mail"];
}
urlString = [self imap4URLString];
@@ -544,20 +500,20 @@ static NSString *spoolFolder = nil;
isEqualToString: urlString])
{
[mailSettings setObject: [self imap4URLString]
forKey: @"folderForExpunge"];
[ud synchronize];
forKey: @"folderForExpunge"];
[us synchronize];
}
}
- (void) expungeLastMarkedFolder
{
NSUserDefaults *ud;
SOGoUserSettings *us;
NSMutableDictionary *mailSettings;
NSString *expungeURL;
NSURL *folderURL;
ud = [[context activeUser] userSettings];
mailSettings = [ud objectForKey: @"Mail"];
us = [[context activeUser] userSettings];
mailSettings = [us objectForKey: @"Mail"];
if (mailSettings)
{
expungeURL = [mailSettings objectForKey: @"folderForExpunge"];
@@ -568,7 +524,7 @@ static NSString *spoolFolder = nil;
if (![[self imap4Connection] expungeAtURL: folderURL])
{
[mailSettings removeObjectForKey: @"folderForExpunge"];
[ud synchronize];
[us synchronize];
}
}
}
@@ -823,6 +779,7 @@ static NSString *spoolFolder = nil;
NSEnumerator *acls;
NSString *currentAcl;
char character;
SOGoIMAPAclStyle aclStyle;
imapAcls = [NSMutableString string];
acls = [sogoAcls objectEnumerator];
@@ -845,6 +802,7 @@ static NSString *spoolFolder = nil;
character = 'a';
else
{
aclStyle = [[self mailAccountFolder] imapAclStyle];
if (aclStyle == rfc2086)
character = [self _rfc2086StyleRight: currentAcl];
else if (aclStyle == rfc4314)
@@ -860,26 +818,6 @@ static NSString *spoolFolder = nil;
return imapAcls;
}
- (void) _unquoteACLUsernames
{
NSMutableDictionary *newIMAPAcls;
NSEnumerator *usernames;
NSString *username, *unquoted;
newIMAPAcls = [NSMutableDictionary new];
usernames = [[mailboxACL allKeys] objectEnumerator];
while ((username = [usernames nextObject]))
{
unquoted = [username substringFromRange:
NSMakeRange(1, [username length] - 2)];
[newIMAPAcls setObject: [mailboxACL objectForKey: username]
forKey: unquoted];
}
[mailboxACL release];
mailboxACL = newIMAPAcls;
}
- (void) _removeIMAPExtUsernames
{
NSMutableDictionary *newIMAPAcls;
@@ -907,9 +845,7 @@ static NSString *spoolFolder = nil;
mailboxACL = [[self imap4Connection] aclForMailboxAtURL: [self imap4URL]];
[mailboxACL retain];
if (aclUsernamesAreQuoted)
[self _unquoteACLUsernames];
if (aclConformsToIMAPExt)
if ([[self mailAccountFolder] imapAclConformsToIMAPExt])
[self _removeIMAPExtUsernames];
}
@@ -1093,12 +1029,15 @@ static NSString *spoolFolder = nil;
- (NSString *) userSpoolFolderPath
{
NSString *login;
NSString *login, *mailSpoolPath;
SOGoUser *currentUser;
login = [[context activeUser] login];
currentUser = [context activeUser];
login = [currentUser login];
mailSpoolPath = [[currentUser domainDefaults] mailSpoolPath];
return [NSString stringWithFormat: @"%@/%@",
spoolFolder, login];
mailSpoolPath, login];
}
- (BOOL) ensureSpoolFolderPath
@@ -1107,7 +1046,8 @@ static NSString *spoolFolder = nil;
fm = [NSFileManager defaultManager];
return ([fm createDirectoriesAtPath: [self userSpoolFolderPath] attributes:nil]);
return ([fm createDirectoriesAtPath: [self userSpoolFolderPath]
attributes: nil]);
}
- (NSString *) displayName
+7 -4
View File
@@ -23,8 +23,9 @@
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGExtensions/NSString+misc.h>
#import <SoObjects/SOGo/SOGoDateFormatter.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/SOGoDateFormatter.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "SOGoMailObject+Draft.h"
#import "SOGoMailForward.h"
@@ -35,7 +36,7 @@
{
if ((self = [super init]))
{
NSUserDefaults *ud;
SOGoUserDefaults *ud;
ud = [[context activeUser] userDefaults];
htmlComposition = [[ud objectForKey: @"ComposeMessagesType"] isEqualToString: @"html"];
@@ -213,8 +214,10 @@
- (NSString *) signature
{
NSString *signature, *mailSignature;
SOGoUserDefaults *ud;
signature = [[context activeUser] signature];
ud = [[context activeUser] userDefaults];
signature = [ud mailSignature];
if ([signature length])
mailSignature = [NSString stringWithFormat: @"-- \n%@", signature];
else
+12 -28
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOResponse.h>
@@ -33,6 +32,7 @@
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserDefaults.h>
#import "NSString+Mail.h"
#import "SOGoMailForward.h"
@@ -43,20 +43,6 @@
@implementation SOGoMailObject (SOGoDraftObjectExtensions)
- (BOOL) useOutlookStyleReplies
{
NSUserDefaults *ud;
static int useOutlookStyleReplies = -1;
if (useOutlookStyleReplies == -1)
{
ud = [NSUserDefaults standardUserDefaults];
useOutlookStyleReplies = [ud boolForKey: @"SOGoMailUseOutlookStyleReplies"];
}
return (useOutlookStyleReplies);
}
- (NSString *) subjectForReply
{
static NSString *replyPrefixes[] = {
@@ -92,13 +78,11 @@
rawHtml: (BOOL) html
{
NSString *rc;
NSUserDefaults *ud;
SOGoUserDefaults *ud;
BOOL htmlComposition;
ud = [[context activeUser] userDefaults];
htmlComposition = [[ud stringForKey: @"ComposeMessagesType"]
isEqualToString: @"html"];
htmlComposition = [[ud mailComposeMessageType] isEqualToString: @"html"];
if (html && !htmlComposition)
rc = [raw htmlToText];
else if (!html && htmlComposition)
@@ -164,19 +148,19 @@
- (NSString *) contentForReply
{
SOGoUser *currentUser;
NSString *pageName;
SOGoMailReply *page;
SOGoUserDefaults *userDefaults;
currentUser = [context activeUser];
userDefaults = [[context activeUser] userDefaults];
pageName = [NSString stringWithFormat: @"SOGoMail%@Reply",
[currentUser language]];
[userDefaults language]];
page = [[WOApplication application] pageWithName: pageName
inContext: context];
[page setSourceMail: self];
[page setOutlookMode: [self useOutlookStyleReplies]];
[page setReplyPlacement: [currentUser replyPlacement]];
[page setSignaturePlacement: [currentUser signaturePlacement]];
[page setOutlookMode: [userDefaults mailUseOutlookStyleReplies]];
[page setReplyPlacement: [userDefaults mailReplyPlacement]];
[page setSignaturePlacement: [userDefaults mailSignaturePlacement]];
return [[page generateResponse] contentAsString];
}
@@ -229,13 +213,13 @@
- (NSString *) contentForInlineForward
{
SOGoUser *currentUser;
SOGoUserDefaults *ud;
NSString *pageName;
SOGoMailForward *page;
currentUser = [context activeUser];
ud = [[context activeUser] userDefaults];
pageName = [NSString stringWithFormat: @"SOGoMail%@Forward",
[currentUser language]];
[ud language]];
page = [[WOApplication application] pageWithName: pageName
inContext: context];
[page setSourceMail: self];
+26 -44
View File
@@ -26,7 +26,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/WOContext.h>
@@ -43,11 +42,12 @@
#import <NGImap4/NGImap4EnvelopeAddress.h>
#import <NGMail/NGMimeMessageParser.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import "NSString+Mail.h"
#import "NSData+Mail.h"
@@ -64,48 +64,30 @@
static NSArray *coreInfoKeys = nil;
static NSString *mailETag = nil;
static BOOL heavyDebug = NO;
static BOOL fetchHeader = YES;
static BOOL debugOn = NO;
static BOOL debugBodyStructure = NO;
static BOOL debugSoParts = NO;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
if ((fetchHeader = ([ud boolForKey: @"SOGoDoNotFetchMailHeader"] ? NO : YES)))
NSLog(@"Note: fetching full mail header.");
else
NSLog(@"Note: not fetching full mail header: 'SOGoDoNotFetchMailHeader'");
/* Note: see SOGoMailManager.m for allowed IMAP4 keys */
/* Note: "BODY" actually returns the structure! */
if (fetchHeader) {
coreInfoKeys = [[NSArray alloc] initWithObjects:
@"FLAGS", @"ENVELOPE", @"BODYSTRUCTURE",
@"RFC822.SIZE",
@"RFC822.HEADER",
// not yet supported: @"INTERNALDATE",
nil];
}
else {
coreInfoKeys = [[NSArray alloc] initWithObjects:
@"FLAGS", @"ENVELOPE", @"BODYSTRUCTURE",
@"RFC822.SIZE",
// not yet supported: @"INTERNALDATE",
nil];
}
if (!coreInfoKeys)
{
/* Note: see SOGoMailManager.m for allowed IMAP4 keys */
coreInfoKeys = [[NSArray alloc] initWithObjects:
@"FLAGS", @"ENVELOPE", @"BODYSTRUCTURE",
@"RFC822.SIZE",
@"RFC822.HEADER",
// not yet supported: @"INTERNALDATE",
nil];
if (![[ud objectForKey: @"SOGoMailDisableETag"] boolValue]) {
mailETag = [[NSString alloc] initWithFormat: @"\"imap4url_%d_%d_%03d\"",
UIX_MAILER_MAJOR_VERSION,
UIX_MAILER_MINOR_VERSION,
UIX_MAILER_SUBMINOR_VERSION];
NSLog(@"Note(SOGoMailObject): using constant etag for mail parts: '%@'",
mailETag);
}
else
NSLog(@"Note(SOGoMailObject): etag caching disabled!");
/* The following disabled code should not be needed, except if we use
annotations (see davEntityTag below) */
// if (![[ud objectForKey: @"SOGoMailDisableETag"] boolValue]) {
mailETag = [[NSString alloc] initWithFormat: @"\"imap4url_%d_%d_%03d\"",
UIX_MAILER_MAJOR_VERSION,
UIX_MAILER_MINOR_VERSION,
UIX_MAILER_SUBMINOR_VERSION];
}
}
- (void) dealloc
@@ -276,12 +258,12 @@ static BOOL debugSoParts = NO;
- (NSCalendarDate *) date
{
NSTimeZone *userTZ;
SOGoUserDefaults *ud;
NSCalendarDate *date;
userTZ = [[context activeUser] timeZone];
ud = [[context activeUser] userDefaults];
date = [[self envelope] date];
[date setTimeZone: userTZ];
[date setTimeZone: [ud timeZone]];
return date;
}
-1
View File
@@ -26,7 +26,6 @@
#import <SoObjects/SOGo/SOGoDateFormatter.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserDefaults.h>
#import "SOGoMailObject+Draft.h"
#import "SOGoMailReply.h"
+12 -2
View File
@@ -26,9 +26,10 @@ SOGo_HEADER_FILES = \
SOGoUserManager.h \
LDAPSource.h \
SQLSource.h \
SOGoUserDefaults.h \
SOGoUserProfile.h \
SOGoDateFormatter.h \
SOGoPermissions.h \
SOGoStartupLogger.h \
iCalEntityObject+Utilities.h \
NSArray+DAV.h \
NSArray+Utilities.h \
@@ -75,12 +76,20 @@ SOGo_OBJC_FILES = \
SOGoParentFolder.m \
SOGoUserFolder.m \
\
SOGoDefaultsSource.m \
SOGoSystemDefaults.m \
SOGoDomainDefaults.m \
SOGoUserDefaults.m \
SOGoUserSettings.m \
\
SOGoDateFormatter.m \
SOGoPermissions.m \
SOGoStartupLogger.m \
SOGoUserManager.m \
LDAPSource.m \
SQLSource.m \
SOGoUserDefaults.m \
SOGoUserProfile.m \
SOGoSQLUserProfile.m \
iCalEntityObject+Utilities.m \
NSArray+DAV.m \
NSArray+Utilities.m \
@@ -115,6 +124,7 @@ SOGo_OBJC_FILES = \
WOContext+SOGo.m
SOGo_RESOURCE_FILES = \
SOGoDefaults.plist \
DAVReportMap.plist
ifeq ($(ldap_config),yes)
+3
View File
@@ -2,6 +2,9 @@
SOGo_INCLUDE_DIRS += -I.. -I../.. -DSOGO_MAJOR_VERSION="\"$(MAJOR_VERSION)\"" -DSOGO_MINOR_VERSION="\"$(MINOR_VERSION)\""
ADDITIONAL_CPPFLAGS += \
-DSOGO_LIBDIR="\"$(SOGO_LIBDIR)\""
SOGo_LIBRARIES_DEPEND_UPON += \
-L../../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \
-L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
+7 -13
View File
@@ -34,6 +34,9 @@
@interface LDAPSource : NSObject <SOGoSource>
{
int queryLimit;
int queryTimeout;
NSString *sourceID;
NSString *bindDN;
NSString *hostname;
@@ -51,15 +54,15 @@
NSString *IMAPHostField;
NSString *bindFields;
NSString *domain;
NSString *contactInfoAttribute;
NSString *domainAttribute;
NSDictionary *modulesConstraints;
NSMutableArray *searchAttributes;
}
+ (id) sourceFromUDSource: (NSDictionary *) udSource;
- (id) initFromUDSource: (NSDictionary *) udSource;
- (void) setBindDN: (NSString *) newBindDN
password: (NSString *) newBindPassword
hostname: (NSString *) newBindHostname
@@ -74,22 +77,13 @@
IMAPHostField: (NSString *) newIMAPHostField
andBindFields: (NSString *) newBindFields;
- (BOOL) checkLogin: (NSString *) login
andPassword: (NSString *) password;
- (NSString *) lookupLoginByDN: (NSString *) theDN;
- (NSDictionary *) lookupContactEntry: (NSString *) theID;
- (NSDictionary *) lookupContactEntryWithUIDorEmail: (NSString *) entryID;
- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID;
- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail;
- (NGLdapEntry *) lookupGroupEntryByAttribute: (NSString *) theAttribute
andValue: (NSString *) theValue;
- (NSArray *) allEntryIDs;
- (NSArray *) fetchContactsMatching: (NSString *) filter;
- (NSString *) sourceID;
- (NSString *) baseDN;
@end
+114 -98
View File
@@ -22,9 +22,7 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSLock.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGExtensions/NSObject+Logs.h>
#import <EOControl/EOControl.h>
@@ -34,35 +32,21 @@
#import "NSArray+Utilities.h"
#import "NSString+Utilities.h"
#import "SOGoDomainDefaults.h"
#import "SOGoSystemDefaults.h"
#import "LDAPSource.h"
#define SafeLDAPCriteria(x) [[x stringByReplacingString: @"\\" withString: @"\\\\"] \
stringByReplacingString: @"'" withString: @"\\'"]
static NSArray *commonSearchFields;
static NSString *LDAPContactInfoAttribute = nil;
static int timeLimit;
static int sizeLimit;
#if defined(THREADSAFE)
static NSLock *lock;
#endif
@implementation LDAPSource
+ (void) initialize
{
NSUserDefaults *ud;
if (!commonSearchFields)
{
ud = [NSUserDefaults standardUserDefaults];
LDAPContactInfoAttribute
= [ud stringForKey: @"SOGoLDAPContactInfoAttribute"];
[LDAPContactInfoAttribute retain];
sizeLimit = [ud integerForKey: @"SOGoLDAPQueryLimit"];
timeLimit = [ud integerForKey: @"SOGoLDAPQueryTimeout"];
commonSearchFields = [NSArray arrayWithObjects:
@"title",
@"company",
@@ -134,18 +118,16 @@ static NSLock *lock;
@"proxyaddresses",
nil];
[commonSearchFields retain];
#if defined(THREADSAFE)
lock = [NSLock new];
#endif
}
}
+ (id) sourceFromUDSource: (NSDictionary *) udSource
inDomain: (NSString *) domain
{
id newSource;
newSource = [[self alloc] initFromUDSource: udSource];
newSource = [[self alloc] initFromUDSource: udSource
inDomain: domain];
[newSource autorelease];
return newSource;
@@ -161,6 +143,7 @@ static NSLock *lock;
encryption = nil;
password = nil;
sourceID = nil;
domain = nil;
baseDN = nil;
IDField = @"cn"; /* the first part of a user DN */
@@ -201,29 +184,77 @@ static NSLock *lock;
}
- (id) initFromUDSource: (NSDictionary *) udSource
inDomain: (NSString *) sourceDomain
{
self = [self init];
NSString *udDomainAttribute;
SOGoDomainDefaults *dd;
NSNumber *udQueryLimit, *udQueryTimeout;
ASSIGN (sourceID, [udSource objectForKey: @"id"]);
if ((self = [self init]))
{
ASSIGN (sourceID, [udSource objectForKey: @"id"]);
[self setBindDN: [udSource objectForKey: @"bindDN"]
password: [udSource objectForKey: @"bindPassword"]
hostname: [udSource objectForKey: @"hostname"]
port: [udSource objectForKey: @"port"]
encryption: [udSource objectForKey: @"encryption"]];
[self setBaseDN: [udSource objectForKey: @"baseDN"]
IDField: [udSource objectForKey: @"IDFieldName"]
CNField: [udSource objectForKey: @"CNFieldName"]
UIDField: [udSource objectForKey: @"UIDFieldName"]
mailFields: [udSource objectForKey: @"MailFieldNames"]
[self setBindDN: [udSource objectForKey: @"bindDN"]
password: [udSource objectForKey: @"bindPassword"]
hostname: [udSource objectForKey: @"hostname"]
port: [udSource objectForKey: @"port"]
encryption: [udSource objectForKey: @"encryption"]];
[self setBaseDN: [udSource objectForKey: @"baseDN"]
IDField: [udSource objectForKey: @"IDFieldName"]
CNField: [udSource objectForKey: @"CNFieldName"]
UIDField: [udSource objectForKey: @"UIDFieldName"]
mailFields: [udSource objectForKey: @"MailFieldNames"]
IMAPHostField: [udSource objectForKey: @"IMAPHostFieldName"]
andBindFields: [udSource objectForKey: @"bindFields"]];
ASSIGN (modulesConstraints,
[udSource objectForKey: @"ModulesConstraints"]);
ASSIGN (_filter, [udSource objectForKey: @"filter"]);
ASSIGN (_scope, ([udSource objectForKey: @"scope"]
? [udSource objectForKey: @"scope"]
: (id)@"sub"));
udDomainAttribute = [udSource objectForKey: @"domainAttribute"];
if ([sourceDomain length])
{
if ([udDomainAttribute length])
{
[self errorWithFormat: @"cannot define 'domainAttribute'"
@" for a domain-based source (%@)", sourceID];
[self release];
self = nil;
}
else
{
dd = [SOGoDomainDefaults defaultsForDomain: sourceDomain];
ASSIGN (domain, sourceDomain);
}
}
else
{
if ([udDomainAttribute length])
ASSIGN (domainAttribute, udDomainAttribute);
dd = [SOGoSystemDefaults sharedSystemDefaults];
}
contactInfoAttribute
= [udSource objectForKey: @"SOGoLDAPContactInfoAttribute"];
if (!contactInfoAttribute)
contactInfoAttribute = [dd ldapContactInfoAttribute];
[contactInfoAttribute retain];
udQueryLimit = [udSource objectForKey: @"SOGoLDAPQueryLimit"];
if (udQueryLimit)
queryLimit = [udQueryLimit intValue];
else
queryLimit = [dd ldapQueryLimit];
udQueryTimeout = [udSource objectForKey: @"SOGoLDAPQueryTimeout"];
if (udQueryTimeout)
queryTimeout = [udQueryTimeout intValue];
else
queryTimeout = [dd ldapQueryTimeout];
ASSIGN (modulesConstraints,
[udSource objectForKey: @"ModulesConstraints"]);
ASSIGN (_filter, [udSource objectForKey: @"filter"]);
ASSIGN (_scope, ([udSource objectForKey: @"scope"]
? [udSource objectForKey: @"scope"]
: (id)@"sub"));
}
return self;
}
@@ -300,10 +331,10 @@ static NSLock *lock;
[ldapConnection bindWithMethod: @"simple"
binddn: bindDN
credentials: password];
if (sizeLimit > 0)
[ldapConnection setQuerySizeLimit: sizeLimit];
if (timeLimit > 0)
[ldapConnection setQueryTimeLimit: timeLimit];
if (queryLimit > 0)
[ldapConnection setQuerySizeLimit: queryLimit];
if (queryTimeout > 0)
[ldapConnection setQueryTimeLimit: queryTimeout];
}
else
ldapConnection = nil;
@@ -318,6 +349,11 @@ static NSLock *lock;
return ldapConnection;
}
- (NSString *) domain
{
return domain;
}
/* user management */
- (EOQualifier *) _qualifierForBindFilter: (NSString *) uid
{
@@ -379,10 +415,6 @@ static NSLock *lock;
NSString *userDN;
NGLdapConnection *bindConnection;
#if defined(THREADSAFE)
[lock lock];
#endif
didBind = NO;
if ([loginToCheck length] > 0)
@@ -391,8 +423,8 @@ static NSLock *lock;
port: port];
if (![encryption length] || [self _setupEncryption: bindConnection])
{
if (timeLimit > 0)
[bindConnection setQueryTimeLimit: timeLimit];
if (queryTimeout > 0)
[bindConnection setQueryTimeLimit: queryTimeout];
if (bindFields)
userDN = [self _fetchUserDNForLogin: loginToCheck];
else
@@ -413,10 +445,6 @@ static NSLock *lock;
[bindConnection release];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
return didBind;
}
@@ -510,8 +538,11 @@ static NSLock *lock;
[searchAttributes addObjectsFromArray: commonSearchFields];
// Add SOGoLDAPContactInfoAttribute from user defaults
if ([LDAPContactInfoAttribute length])
[searchAttributes addObjectUniquely: LDAPContactInfoAttribute];
if ([contactInfoAttribute length])
[searchAttributes addObjectUniquely: contactInfoAttribute];
if ([domainAttribute length])
[searchAttributes addObjectUniquely: domainAttribute];
// Add IMAP hostname from user defaults
if ([IMAPHostField length])
@@ -530,10 +561,6 @@ static NSLock *lock;
NSArray *attributes;
NSMutableArray *ids;
#if defined(THREADSAFE)
[lock lock];
#endif
ids = [NSMutableArray array];
ldapConnection = [self _ldapConnection];
@@ -559,10 +586,6 @@ static NSLock *lock;
[ids addObject: value];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
return ids;
}
@@ -697,6 +720,31 @@ static NSLock *lock;
if (!value)
value = @"";
[contactEntry setObject: value forKey: @"c_cn"];
if (contactInfoAttribute)
{
value = [[ldapEntry attributeWithName: contactInfoAttribute]
stringValueAtIndex: 0];
if (!value)
value = @"";
}
else
value = @"";
[contactEntry setObject: value forKey: @"c_info"];
if (domainAttribute)
{
value = [[ldapEntry attributeWithName: domainAttribute]
stringValueAtIndex: 0];
if (!value)
value = @"";
}
else if (domain)
value = domain;
else
value = @"";
[contactEntry setObject: value forKey: @"c_domain"];
[self _fillEmailsOfEntry: ldapEntry intoContactEntry: contactEntry];
[self _fillConstraints: ldapEntry forModule: @"Calendar"
intoContactEntry: (NSMutableDictionary *) contactEntry];
@@ -715,10 +763,6 @@ static NSLock *lock;
EOQualifier *qualifier;
NSArray *attributes;
#if defined(THREADSAFE)
[lock lock];
#endif
contacts = [NSMutableArray array];
if ([match length] > 0)
@@ -744,10 +788,6 @@ static NSLock *lock;
[self _convertLDAPEntryToContact: currentEntry]];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
return contacts;
}
@@ -761,10 +801,6 @@ static NSLock *lock;
NSString *s;
NSDictionary *contactEntry;
#if defined(THREADSAFE)
[lock lock];
#endif
contactEntry = nil;
if ([theID length] > 0)
@@ -793,10 +829,6 @@ static NSLock *lock;
contactEntry = [self _convertLDAPEntryToContact: ldapEntry];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
return contactEntry;
}
@@ -809,10 +841,6 @@ static NSLock *lock;
NSArray *attributes;
NSDictionary *contactEntry;
#if defined(THREADSAFE)
[lock lock];
#endif
contactEntry = nil;
if ([uid length] > 0)
@@ -839,10 +867,6 @@ static NSLock *lock;
contactEntry = [self _convertLDAPEntryToContact: ldapEntry];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
return contactEntry;
}
@@ -887,10 +911,6 @@ static NSLock *lock;
NGLdapConnection *ldapConnection;
NGLdapEntry *ldapEntry;
#if defined(THREADSAFE)
[lock lock];
#endif
if ([theValue length] > 0)
{
ldapConnection = [self _ldapConnection];
@@ -898,7 +918,7 @@ static NSLock *lock;
s = [NSString stringWithFormat: @"(%@='%@')",
theAttribute, SafeLDAPCriteria (theValue)];
qualifier = [EOQualifier qualifierWithQualifierFormat: s];
// We look for additional attributes - the ones related to group
// membership
attributes = [NSMutableArray arrayWithArray: [self _searchAttributes]];
@@ -925,10 +945,6 @@ static NSLock *lock;
else
ldapEntry = nil;
#if defined(THREADSAFE)
[lock unlock];
#endif
return ldapEntry;
}
+2
View File
@@ -62,6 +62,8 @@
- (BOOL) boolValue;
#endif
- (int) timeValue;
// LDIF
- (BOOL) _isLDIFSafe;
+18
View File
@@ -385,6 +385,24 @@ static NSMutableCharacterSet *urlStartChars = nil;
}
#endif
- (int) timeValue
{
int i, time;
if ([self length] > 0)
{
i = [self rangeOfString: @":"].location;
if (i == NSNotFound)
time = [self intValue];
else
time = [[self substringToIndex: i] intValue];
}
else
time = -1;
return time;
}
static NSMutableCharacterSet *safeLDIFChars = nil;
static NSMutableCharacterSet *safeLDIFStartChars = nil;
+2 -1
View File
@@ -41,12 +41,13 @@
NSMutableDictionary *localCache;
NSMutableDictionary *cache;
NSMutableDictionary *users;
float cleanupInterval;
NSString *memcachedServerName;
@private
memcached_server_st *servers;
memcached_st *handle;
}
+ (NSTimeInterval) cleanupInterval;
+ (SOGoCache *) sharedCache;
- (void) killCache;
+18 -68
View File
@@ -36,95 +36,43 @@
#import <Foundation/NSLock.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimer.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/SoObject.h>
#import <NGExtensions/NSObject+Logs.h>
#import "SOGoObject.h"
#import "SOGoSystemDefaults.h"
#import "SOGoUser.h"
#import "SOGoUserDefaults.h"
#import "SOGoUserProfile.h"
#import "SOGoCache.h"
// We define the default value for cleaning up cached
// users' preferences. This value should be relatively
// high to avoid useless database calls.
static NSTimeInterval cleanupInterval = 0;
static NSString *memcachedServerName;
#if defined(THREADSAFE)
static NSLock *lock;
#endif
@implementation SOGoCache
+ (void) initialize
{
NSString *cleanupSetting;
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
// We fire our timer that will cleanup cache entries
cleanupSetting = [ud objectForKey: @"SOGoCacheCleanupInterval"];
if (cleanupSetting && [cleanupSetting doubleValue] > 0.0)
cleanupInterval = [cleanupSetting doubleValue];
if (cleanupInterval == 0.0)
cleanupInterval = 300;
[self logWithFormat: @"Cache cleanup interval set every %f seconds for memcached",
cleanupInterval];
ASSIGN (memcachedServerName, [ud stringForKey: @"SOGoMemCachedHost"]);
if (!memcachedServerName)
memcachedServerName = @"localhost";
[self logWithFormat: @"Using host '%@' as memcached server",
memcachedServerName];
#if defined(THREADSAFE)
lock = [NSLock new];
#endif
}
+ (NSTimeInterval) cleanupInterval
{
return cleanupInterval;
}
+ (SOGoCache *) sharedCache
{
static SOGoCache *sharedCache = nil;
#if defined(THREADSAFE)
[lock lock];
#endif
if (!sharedCache)
sharedCache = [self new];
#if defined(THREADSAFE)
[lock unlock];
#endif
return sharedCache;
}
- (void) killCache
{
#if defined(THREADSAFE)
[lock lock];
#endif
[cache removeAllObjects];
// This is essential for refetching the cached values in case something has changed
// accross various sogod processes
[users removeAllObjects];
[localCache removeAllObjects];
#if defined(THREADSAFE)
[lock unlock];
#endif
}
- (id) init
{
SOGoSystemDefaults *sd;
if ((self = [super init]))
{
memcached_return error;
@@ -145,6 +93,19 @@ static NSLock *lock;
{
#warning We could also make the port number configurable and even make use \
of NGNetUtilities for that.
sd = [SOGoSystemDefaults sharedSystemDefaults];
// We define the default value for cleaning up cached users'
// preferences. This value should be relatively high to avoid
// useless database calls.
cleanupInterval = [sd cacheCleanupInterval];
ASSIGN (memcachedServerName, [sd memcachedHost]);
[self logWithFormat: @"Cache cleanup interval set every %f seconds",
cleanupInterval];
[self logWithFormat: @"Using host '%@' as server",
memcachedServerName];
servers
= memcached_server_list_append(NULL,
[memcachedServerName UTF8String],
@@ -160,6 +121,7 @@ static NSLock *lock;
{
memcached_server_free(servers);
memcached_free(handle);
[memcachedServerName release];
[cache release];
[users release];
[localCache release];
@@ -206,16 +168,10 @@ static NSLock *lock;
inContainer: [container container]];
fullPath = [self _pathFromObject: container
withName: name];
#if defined(THREADSAFE)
[lock lock];
#endif
if (![cache objectForKey: fullPath])
{
[cache setObject: object forKey: fullPath];
}
#if defined(THREADSAFE)
[lock unlock];
#endif
}
}
@@ -235,13 +191,7 @@ static NSLock *lock;
- (void) registerUser: (SOGoUser *) user
withName: (NSString *) userName
{
#if defined(THREADSAFE)
[lock lock];
#endif
[users setObject: user forKey: userName];
#if defined(THREADSAFE)
[lock unlock];
#endif
}
- (id) userNamed: (NSString *) name
-1
View File
@@ -21,7 +21,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
+2 -2
View File
@@ -19,9 +19,9 @@
02111-1307, USA.
*/
#import <Foundation/NSDictionary.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSUserDefaults.h> /* for NSXXXFormatString, ... */
#import "SOGoDateFormatter.h"
+64
View File
@@ -0,0 +1,64 @@
{
WOWorkersCount = 1;
SxVMemLimit = 384;
WOLogFile = "/var/log/sogo/sogo.log";
WOPidFile = "/var/log/run/sogo.pid";
SOGoZipPath = "/usr/bin/zip";
WOUseRelativeURLs = YES;
WOMessageUseUTF8 = YES;
WOParsersUseUTF8 = YES;
NGUseUTF8AsURLEncoding = YES;
SOGoCacheCleanupInterval = 300.0;
SOGoMemcachedHost = "localhost";
SOGoUIxDebugEnabled = NO;
SOGoLDAPContactInfoAttribute = "description";
SOGoMailingMechanism = "sendmail";
SOGoSMTPServer = "localhost";
SOGoMailSpoolPath = "/tmp";
SOGoLoginModule = "Mail";
SOGoLanguage = "English";
SOGoSupportedLanguages = ( "Czech", "Welsh", "English", "Spanish",
"French", "German", "Italian", "Hungarian",
"Dutch", "BrazilianPortuguese", "Russian",
"Swedish");
SOGoTimeZone = "UTC";
SOGoDayStartTime = "8";
SOGoDayEndTime = "18";
SOGoTimeFormat = "%H:00";
SOGoIMAPServer = "localhost";
SOGoFirstDayOfWeek = 0;
SOGoFirstWeekOfYear = "January1";
SOGoMailDomain = "localhost";
SOGoMailMessageCheck = "manually";
SOGoMailMessageForwarding = "inline";
SOGoMailReplyPlacement = "below";
SOGoMailSignaturePlacement = "below";
SOGoMailPollingIntervals = ( 1, 2, 5, 10, 20, 30, 30 );
SOGoMailComposeMessageType = "text";
SOGoMailListViewColumnsOrder = ( "Flagged", "Attachment", "Subject",
"From", "Unread", "Date", "Priority",
"Size" );
SOGoSentFolderName = "Sent";
SOGoDraftsFolderName = "Drafts";
SOGoTrashFolderName = "Trash";
SOGoOtherUsersFolderName = "Other Users";
SOGoSharedFolderName = "Shared Folders";
SOGoCalendarShouldDisplayWeekend = YES;
SOGoFreeBusyDefaultInterval = ( 7, 7 );
SOGoReminderEnabled = YES;
SOGoRemindWithASound = YES;
}
+81
View File
@@ -0,0 +1,81 @@
/* SOGoDefaultsSource.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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.
*/
/* A proxy to a NSUserDefauts intance (or compatible) and to a parent
source. */
#ifndef SOGODEFAULTSSOURCE_H
#define SOGODEFAULTSSOURCE_H
@class NSArray;
@class NSData;
@class NSDictionary;
@class NSString;
extern NSString *SOGoDefaultsSourceInvalidSource;
extern NSString *SOGoDefaultsSourceUnmutableSource;
@interface SOGoDefaultsSource : NSObject
{
id source;
SOGoDefaultsSource *parentSource;
BOOL isMutable;
}
+ (id) defaultsSourceWithSource: (id) newSource
andParentSource: (SOGoDefaultsSource *) newParentSource;
- (void) setSource: (id) newSource;
- (id) source;
- (void) setParentSource: (SOGoDefaultsSource *) newParentSource;
/* db management */
- (BOOL) migrate;
- (BOOL) migrateOldDefaultsWithDictionary: (NSDictionary *) migratedKeys;
- (BOOL) synchronize;
/* accessors */
- (void) setObject: (id) value forKey: (NSString *) key;
- (id) objectForKey: (NSString *) objectKey;
- (void) removeObjectForKey: (NSString *) key;
- (void) setBool: (BOOL) value forKey: (NSString *) key;
- (BOOL) boolForKey: (NSString *) key;
- (void) setFloat: (float) value forKey: (NSString *) key;
- (float) floatForKey: (NSString *) key;
- (NSArray *) arrayForKey: (NSString *) key;
- (NSArray *) stringArrayForKey: (NSString *) key;
- (void) setInteger: (int) value forKey: (NSString *) key;
- (int) integerForKey: (NSString *) key;
- (id) dictionaryForKey: (NSString *) key;
- (NSData *) dataForKey: (NSString *) key;
- (NSString *) stringForKey: (NSString *) key;
@end
#endif /* SOGODEFAULTSSOURCE_H */
+248
View File
@@ -0,0 +1,248 @@
/* SOGoDefaultsSource.m - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NSObject+Logs.h>
#define NEEDS_DEFAULTS_SOURCE_INTERNAL 1
#import "SOGoDefaultsSource.h"
NSString *SOGoDefaultsSourceInvalidSource = @"SOGoDefaultsSourceInvalidSource";
NSString *SOGoDefaultsSourceUnmutableSource = @"SOGoDefaultsSourceUnmutableSource";
@implementation SOGoDefaultsSource
+ (id) defaultsSourceWithSource: (id) newSource
andParentSource: (SOGoDefaultsSource *) newParentSource
{
SOGoDefaultsSource *sogoDefaultsSource;
sogoDefaultsSource = [self new];
[sogoDefaultsSource autorelease];
[sogoDefaultsSource setSource: newSource];
[sogoDefaultsSource setParentSource: newParentSource];
if ([sogoDefaultsSource migrate])
[sogoDefaultsSource synchronize];
return sogoDefaultsSource;
}
- (id) init
{
if ((self = [super init]))
{
source = nil;
parentSource = nil;
isMutable = NO;
}
return self;
}
- (void) dealloc
{
[source release];
[parentSource release];
[super dealloc];
}
- (void) setSource: (id) newSource
{
if ([newSource respondsToSelector: @selector (objectForKey:)])
{
ASSIGN (source, newSource);
isMutable = [source respondsToSelector: @selector (setObject:forKey:)];
}
else
[NSException raise: SOGoDefaultsSourceInvalidSource
format: @"UserDefaults source '%@'"
@" does not respond to 'object:forKey:'", newSource];
}
- (id) source
{
return source;
}
- (void) setParentSource: (SOGoDefaultsSource *) newParentSource
{
ASSIGN (parentSource, newParentSource);
}
- (void) setObject: (id) value
forKey: (NSString *) key
{
if (isMutable)
[source setObject: value forKey: key];
else
[NSException raise: SOGoDefaultsSourceUnmutableSource
format: @"UserDefaults source '%@' is not mutable", source];
}
- (id) objectForKey: (NSString *) objectKey
{
id objectForKey;
objectForKey = [source objectForKey: objectKey];
if (!objectForKey)
objectForKey = [parentSource objectForKey: objectKey];
return objectForKey;
}
- (void) removeObjectForKey: (NSString *) key
{
[source removeObjectForKey: key];
}
- (void) setBool: (BOOL) value
forKey: (NSString *) key
{
[self setObject: [NSNumber numberWithBool: value]
forKey: key];
}
- (BOOL) boolForKey: (NSString *) key
{
return [[self objectForKey: key] boolValue];
}
- (void) setFloat: (float) value
forKey: (NSString *) key
{
[self setObject: [NSNumber numberWithFloat: value]
forKey: key];
}
- (float) floatForKey: (NSString *) key
{
return [[self objectForKey: key] floatValue];
}
- (void) setInteger: (int) value
forKey: (NSString *) key
{
[self setObject: [NSString stringWithFormat: @"%d", value]
forKey: key];
}
- (int) integerForKey: (NSString *) key
{
return [[self objectForKey: key] intValue];
}
#warning TODO: type checking
- (NSArray *) arrayForKey: (NSString *) key
{
return [self objectForKey: key];
}
- (NSArray *) stringArrayForKey: (NSString *) key
{
return [self objectForKey: key];
}
- (NSData *) dataForKey: (NSString *) key
{
return [self objectForKey: key];
}
- (NSString *) stringForKey: (NSString *) key
{
return [self objectForKey: key];
}
/* Dictionaries are a special case for which we don't allow searches in the
parent source. Each level can thus have its own set of dictionary values. */
- (id) dictionaryForKey: (NSString *) objectKey
{
id objectForKey;
objectForKey = [source objectForKey: objectKey];
return objectForKey;
}
- (BOOL) migrate
{
return NO;
}
- (BOOL) migrateOldDefaultsWithDictionary: (NSDictionary *) migratedKeys
{
NSArray *allKeys;
id currentValue, existingValue;
NSString *oldName, *newName;
int count, max;
BOOL requireSync;
requireSync = NO;
allKeys = [migratedKeys allKeys];
max = [allKeys count];
for (count = 0; count < max; count++)
{
oldName = [allKeys objectAtIndex: count];
currentValue = [source objectForKey: oldName];
if (currentValue)
{
newName = [migratedKeys objectForKey: oldName];
existingValue = [source objectForKey: newName];
if (existingValue)
[self errorWithFormat: @"both old and new defaults key"
@" '%@' '%@' exist. Migration skipped.", oldName, newName];
else
{
requireSync = YES;
[source setObject: currentValue forKey: newName];
[source removeObjectForKey: oldName];
[self warnWithFormat: @"defaults key '%@' was renamed to '%@'",
oldName, newName];
}
}
}
return requireSync;
}
- (BOOL) synchronize
{
BOOL rc;
if ([source respondsToSelector: @selector (synchronize)])
rc = [source synchronize];
else
{
[self errorWithFormat: @"current source cannot synchronize defaults"];
rc = NO;
}
return rc;
}
@end
+69
View File
@@ -0,0 +1,69 @@
/* SOGoDomainDefaults.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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 SOGODOMAINDEFAULTS_H
#define SOGODOMAINDEFAULTS_H
#import <SOGo/SOGoLDAPDefaults.h>
#import <SOGo/SOGoUserDefaults.h>
@interface SOGoDomainDefaults : SOGoUserDefaults <SOGoLDAPDefaults>
+ (SOGoDomainDefaults *) defaultsForDomain: (NSString *) domainId;
- (NSString *) profileURL;
- (NSString *) folderInfoURL;
- (NSArray *) superUsernames;
- (NSArray *) userSources;
- (NSString *) mailDomain;
- (NSString *) imapServer;
- (NSString *) imapAclStyle;
- (BOOL) imapAclConformsToIMAPExt;
- (BOOL) forceIMAPLoginWithEmail;
- (BOOL) forwardEnabled;
- (BOOL) vacationEnabled;
- (NSString *) otherUsersFolderName;
- (NSString *) sharedFolderName;
- (NSString *) mailingMechanism;
- (NSString *) smtpServer;
- (NSString *) mailSpoolPath;
- (float) softQuotaRatio;
- (BOOL) mailKeepDraftsAfterSend;
- (BOOL) mailAttachTextDocumentsInline;
- (NSArray *) mailListViewColumnsOrder;
- (BOOL) aclSendEMailNotifications;
- (BOOL) appointmentSendEMailNotifications;
- (BOOL) foldersSendEMailNotifications;
- (NSArray *) calendarDefaultRoles;
- (NSArray *) contactsDefaultRoles;
- (NSArray *) mailPollingIntervals;
- (NSArray *) freeBusyDefaultInterval;
- (int) davCalendarStartTimeLimit;
@end
#endif /* SOGODOMAINDEFAULTS_H */
+285
View File
@@ -0,0 +1,285 @@
/* SOGoDomainDefaults.m - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
#import <NGExtensions/NSObject+Logs.h>
#define NEEDS_DEFAULTS_SOURCE_INTERNAL 1
#import "SOGoSystemDefaults.h"
#import "SOGoDomainDefaults.h"
@implementation SOGoDomainDefaults
+ (SOGoDomainDefaults *) defaultsForDomain: (NSString *) domainId
{
NSDictionary *domainValues;
SOGoSystemDefaults *systemDefaults;
SOGoDomainDefaults *domainDefaults;
domainDefaults = nil;
if ([domainId length])
{
systemDefaults = [SOGoSystemDefaults sharedSystemDefaults];
domainValues = [[systemDefaults dictionaryForKey: @"domains"]
objectForKey: domainId];
if ([domainValues isKindOfClass: [NSDictionary class]])
{
domainDefaults
= [SOGoDomainDefaults defaultsSourceWithSource: domainValues
andParentSource: systemDefaults];
}
}
return domainDefaults;
}
- (BOOL) migrate
{
static NSDictionary *migratedKeys = nil;
if (!migratedKeys)
{
migratedKeys
= [NSDictionary dictionaryWithObjectsAndKeys:
@"SOGoIMAPServer", @"SOGoFallbackIMAP4Server",
@"SOGoMailDomain", @"SOGoDefaultMailDomain",
@"SOGoLDAPContactInfoAttribute", @"LDAPContactInfoAttribute",
@"SOGoUserSources", @"SOGoLDAPSources",
@"SOGoMailKeepDraftsAfterSend", @"SOGoNoDraftDeleteAfterSend",
@"SOGoMailAttachTextDocumentsInline", @"SOGoShowTextAttachmentsInline",
nil];
[migratedKeys retain];
}
/* we must not use a boolean operation, otherwise subsequent migrations will
not even occur in the case where rc = YES. */
return ([self migrateOldDefaultsWithDictionary: migratedKeys]
| [super migrate]);
}
- (NSArray *) userSources
{
return [source objectForKey: @"SOGoUserSources"];
}
/* System-/Domain-level */
// SOGoDontUseETagsForMailViewer
- (NSString *) profileURL
{
return [self stringForKey: @"SOGoProfileURL"];
}
- (NSString *) folderInfoURL
{
return [self stringForKey: @"OCSFolderInfoURL"];
}
- (NSString *) mailDomain
{
return [self stringForKey: @"SOGoMailDomain"];
}
- (NSString *) imapServer
{
return [self stringForKey: @"SOGoIMAPServer"];
}
#warning should be removed when we make use of imap namespace
- (NSString *) imapAclStyle
{
return [self stringForKey: @"SOGoIMAPAclStyle"];
}
#warning this should be determined from the capabilities
/* http://www.tools.ietf.org/wg/imapext/draft-ietf-imapext-acl/ */
- (BOOL) imapAclConformsToIMAPExt
{
return [self boolForKey: @"SOGoIMAPAclConformsToIMAPExt"];
}
- (BOOL) aclSendEMailNotifications
{
return [self boolForKey: @"SOGoACLsSendEMailNotifications"];
}
- (BOOL) appointmentSendEMailNotifications
{
return [self boolForKey: @"SOGoAppointmentSendEMailNotifications"];
}
- (BOOL) foldersSendEMailNotifications
{
return [self boolForKey: @"SOGoFoldersSendEMailNotifications"];
}
- (NSArray *) calendarDefaultRoles
{
return [self stringArrayForKey: @"SOGoCalendarDefaultRoles"];
}
- (NSArray *) contactsDefaultRoles
{
return [self stringArrayForKey: @"SOGoContactsDefaultRoles"];
}
- (BOOL) forceIMAPLoginWithEmail
{
return [self boolForKey: @"SOGoForceIMAPLoginWithEmail"];
}
- (BOOL) forwardEnabled
{
return [self boolForKey: @"SOGoForceIMAPLoginWithEmail"];
}
- (BOOL) vacationEnabled
{
return [self boolForKey: @"SOGoForceIMAPLoginWithEmail"];
}
- (NSString *) mailingMechanism
{
NSString *mailingMechanism;
mailingMechanism = [self stringForKey: @"SOGoMailingMechanism"];
if (!([mailingMechanism isEqualToString: @"sendmail"]
|| [mailingMechanism isEqualToString: @"smtp"]))
{
[self logWithFormat: @"mechanism '%@' is invalid and"
@" should be set to 'sendmail' or 'smtp' instead",
mailingMechanism];
mailingMechanism = nil;
}
return mailingMechanism;
}
- (NSArray *) mailPollingIntervals
{
return [self arrayForKey: @"SOGoMailPollingIntervals"];
}
- (NSString *) otherUsersFolderName
{
return [self stringForKey: @"SOGoOtherUsersFolderName"];
}
- (NSString *) sharedFolderName
{
return [self stringForKey: @"SOGoSharedFolderName"];
}
- (NSString *) smtpServer
{
return [self stringForKey: @"SOGoSMTPServer"];
}
- (NSString *) mailSpoolPath
{
return [self stringForKey: @"SOGoMailSpoolPath"];
}
- (float) softQuotaRatio
{
return [self floatForKey: @"SOGoSoftQuotaRatio"];
}
- (BOOL) mailKeepDraftsAfterSend
{
return [self boolForKey: @"SOGoMailKeepDraftsAfterSend"];
}
- (BOOL) mailAttachTextDocumentsInline
{
return [self boolForKey: @"SOGoMailAttachTextDocumentsInline"];
}
- (NSArray *) mailListViewColumnsOrder
{
return [self stringArrayForKey: @"SOGoMailListViewColumnsOrder"];
}
- (NSArray *) superUsernames
{
return [self stringArrayForKey: @"SOGoSuperUsernames"];
}
/* System-/Domain-/LDAP-level */
- (int) ldapQueryLimit
{
return [self integerForKey: @"SOGoLDAPQueryLimit"];
}
- (int) ldapQueryTimeout
{
return [self integerForKey: @"SOGoLDAPQueryTimeout"];
}
- (NSString *) ldapContactInfoAttribute
{
return [self stringForKey: @"SOGoLDAPContactInfoAttribute"];
}
- (NSArray *) freeBusyDefaultInterval
{
return [self arrayForKey: @"SOGoFreeBusyDefaultInterval"];
}
- (int) davCalendarStartTimeLimit
{
return [self integerForKey: @"SOGoDAVCalendarStartTimeLimit"];
}
/* overriden methods */
- (NSString *) language
{
NSArray *browserLanguages, *supportedLanguages;
NSString *language;
WOContext *context;
/* When we end up here, which means the active user has no language set, we
fetch the list of languages that are accepted by his/her browser and we
take the first of those which is supported. This ensures that the
resulting languages is always available. If not, we fallback on the
language of the domain or SOGo. */
context = [[WOApplication application] context];
browserLanguages = [[context request] browserLanguages];
supportedLanguages = [[SOGoSystemDefaults sharedSystemDefaults]
supportedLanguages];
language = [browserLanguages
firstObjectCommonWithArray: supportedLanguages];
if (!(language && [language isKindOfClass: [NSString class]]))
language = [self stringForKey: @"SOGoLanguage"];
return language;
}
@end
+35 -31
View File
@@ -29,7 +29,6 @@
#import <Foundation/NSException.h>
#import <Foundation/NSKeyValueCoding.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/NSException+HTTP.h>
@@ -54,8 +53,8 @@
#import <GDLContentStore/NSURL+GCS.h>
#import <SaxObjC/XMLNamespaces.h>
#import <UI/SOGoUI/SOGoFolderAdvisory.h>
#import "NSDictionary+Utilities.h"
#import "NSDictionary+Utilities.h"
#import "NSArray+Utilities.h"
#import "NSArray+DAV.h"
#import "NSObject+DAV.h"
@@ -65,10 +64,13 @@
#import "DOMNode+SOGo.h"
#import "SOGoCache.h"
#import "SOGoContentObject.h"
#import "SOGoDomainDefaults.h"
#import "SOGoGroup.h"
#import "SOGoParentFolder.h"
#import "SOGoPermissions.h"
#import "SOGoUser.h"
#import "SOGoUserDefaults.h"
#import "SOGoUserSettings.h"
#import "SOGoWebDAVAclManager.h"
#import "WORequest+SOGo.h"
#import "WOResponse+SOGo.h"
@@ -76,7 +78,6 @@
#import "SOGoGCSFolder.h"
static NSString *defaultUserID = @"<default>";
static BOOL sendFolderAdvisories = NO;
static NSArray *childRecordFields = nil;
@implementation SOGoGCSFolder
@@ -139,11 +140,6 @@ static NSArray *childRecordFields = nil;
+ (void) initialize
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
sendFolderAdvisories = [ud boolForKey: @"SOGoFoldersSendEMailNotifications"];
if (!childRecordFields)
{
childRecordFields = [NSArray arrayWithObjects: @"c_name", @"c_version",
@@ -389,12 +385,14 @@ static NSArray *childRecordFields = nil;
NSString *pageName;
SOGoUser *user;
SOGoFolderAdvisory *page;
NSString *language;
if (sendFolderAdvisories)
user = [SOGoUser userWithLogin: [self ownerInContext: context]];
if ([[user domainDefaults] foldersSendEMailNotifications])
{
user = [SOGoUser userWithLogin: [self ownerInContext: context]];
language = [[user userDefaults] language];
pageName = [NSString stringWithFormat: @"SOGoFolder%@%@Advisory",
[user language], template];
language, template];
page = [[WOApplication application] pageWithName: pageName
inContext: context];
@@ -676,7 +674,7 @@ static NSArray *childRecordFields = nil;
{
NSMutableArray *folderSubscription, *tmpA;
NSString *subscriptionPointer;
NSUserDefaults *ud;
SOGoUserSettings *us;
NSMutableDictionary *moduleSettings, *tmpD;
SOGoUser *sogoUser;
BOOL rc;
@@ -684,13 +682,13 @@ static NSArray *childRecordFields = nil;
sogoUser = [SOGoUser userWithLogin: subscribingUser roles: nil];
if (sogoUser)
{
ud = [sogoUser userSettings];
moduleSettings = [ud objectForKey: [container nameInContainer]];
us = [sogoUser userSettings];
moduleSettings = [us objectForKey: [container nameInContainer]];
if (!(moduleSettings
&& [moduleSettings isKindOfClass: [NSMutableDictionary class]]))
{
moduleSettings = [NSMutableDictionary dictionary];
[ud setObject: moduleSettings forKey: [container nameInContainer]];
[us setObject: moduleSettings forKey: [container nameInContainer]];
}
folderSubscription
@@ -731,7 +729,7 @@ static NSArray *childRecordFields = nil;
[folderSubscription removeObject: subscriptionPointer];
}
[ud synchronize];
[us synchronize];
rc = YES;
}
else
@@ -1203,11 +1201,13 @@ static NSArray *childRecordFields = nil;
{
int count, max;
NSDictionary *record;
NSString *currentUID;
NSString *currentUID, *domain;
SOGoGroup *group;
NSMutableArray *acls;
acls = [NSMutableArray array];
#warning should it be the domain of the ownerUser instead?
domain = [[context activeUser] domain];
max = [records count];
for (count = 0; count < max; count++)
@@ -1216,7 +1216,8 @@ static NSArray *childRecordFields = nil;
currentUID = [record valueForKey: @"c_uid"];
if ([currentUID hasPrefix: @"@"])
{
group = [SOGoGroup groupWithIdentifier: currentUID];
group = [SOGoGroup groupWithIdentifier: currentUID
inDomain: domain];
if (group && [group hasMemberWithUID: uid])
[acls addObject: [record valueForKey: @"c_role"]];
}
@@ -1268,8 +1269,9 @@ static NSArray *childRecordFields = nil;
forObjectAtPath: (NSArray *) objectPathArray
{
NSArray *acls;
NSString *objectPath;
NSString *objectPath, *module;
NSDictionary *aclsForObject;
SOGoDomainDefaults *dd;
objectPath = [objectPathArray componentsJoinedByString: @"/"];
aclsForObject = [aclCache objectForKey: objectPath];
@@ -1286,18 +1288,18 @@ static NSArray *childRecordFields = nil;
}
if (!([acls count] || [uid isEqualToString: defaultUserID]))
acls = [self aclsForUser: defaultUserID
forObjectAtPath: objectPathArray];
acls = [self aclsForUser: defaultUserID forObjectAtPath: objectPathArray];
// If we still don't have ACLs defined for this particular resource,
// let's go get the system-wide defaults, if any.
// let's go get the domain defaults, if any.
if (![acls count])
{
if ([[container nameInContainer] isEqualToString: @"Calendar"]
|| [[container nameInContainer] isEqualToString: @"Contacts"])
acls = [[NSUserDefaults standardUserDefaults]
objectForKey: [NSString stringWithFormat: @"SOGo%@DefaultRoles",
[container nameInContainer]]];
dd = [[context activeUser] domainDefaults];
module = [container nameInContainer];
if ([module isEqualToString: @"Calendar"])
acls = [dd calendarDefaultRoles];
else if ([module isEqualToString: @"Contacts"])
acls = [dd contactsDefaultRoles];
}
return acls;
@@ -1307,7 +1309,7 @@ static NSArray *childRecordFields = nil;
forObjectAtPath: (NSArray *) objectPathArray
{
EOQualifier *qualifier;
NSString *uid, *uids, *qs, *objectPath;
NSString *uid, *uids, *qs, *objectPath, *domain;
NSMutableArray *usersAndGroups;
NSMutableDictionary *aclsForObject;
SOGoGroup *group;
@@ -1315,6 +1317,7 @@ static NSArray *childRecordFields = nil;
if ([users count] > 0)
{
domain = [[context activeUser] domain];
usersAndGroups = [NSMutableArray arrayWithArray: users];
for (i = 0; i < [usersAndGroups count]; i++)
{
@@ -1322,7 +1325,7 @@ static NSArray *childRecordFields = nil;
if (![uid hasPrefix: @"@"])
{
// Prefix the UID with the character "@" when dealing with a group
group = [SOGoGroup groupWithIdentifier: uid];
group = [SOGoGroup groupWithIdentifier: uid inDomain: domain];
if (group)
[usersAndGroups replaceObjectAtIndex: i
withObject: [NSString stringWithFormat: @"@%@", uid]];
@@ -1372,7 +1375,7 @@ static NSArray *childRecordFields = nil;
forUser: (NSString *) uid
forObjectAtPath: (NSArray *) objectPathArray
{
NSString *objectPath, *aUID;
NSString *objectPath, *aUID, *domain;
NSMutableArray *newRoles;
SOGoGroup *group;
@@ -1380,7 +1383,8 @@ static NSArray *childRecordFields = nil;
if (![uid hasPrefix: @"@"])
{
// Prefix the UID with the character "@" when dealing with a group
group = [SOGoGroup groupWithIdentifier: uid];
domain = [[context activeUser] domain];
group = [SOGoGroup groupWithIdentifier: uid inDomain: domain];
if (group)
aUID = [NSString stringWithFormat: @"@%@", uid];
}
+6 -3
View File
@@ -40,10 +40,13 @@
NSMutableArray *_members;
}
+ (id) groupWithIdentifier: (NSString *) theID;
+ (id) groupWithEmail: (NSString *) theEmail;
+ (id) groupWithIdentifier: (NSString *) theID
inDomain: (NSString *) domain;
+ (id) groupWithEmail: (NSString *) theEmail
inDomain: (NSString *) domain;
+ (id) groupWithValue: (NSString *) theValue
andSourceSelector: (SEL) theSelector;
andSourceSelector: (SEL) theSelector
inDomain: (NSString *) domain;
- (NSArray *) members;
+14 -8
View File
@@ -50,7 +50,7 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#include "LDAPSource.h"
#include "SOGoSource.h"
#include "SOGoUserManager.h"
#include "SOGoUser.h"
@@ -61,7 +61,7 @@
@implementation SOGoGroup
- (id) initWithIdentifier: (NSString *) theID
source: (LDAPSource *) theSource
source: (NSObject <SOGoSource> *) theSource
entry: (NGLdapEntry *) theEntry
{
self = [super init];
@@ -88,19 +88,23 @@
}
+ (id) groupWithIdentifier: (NSString *) theID
inDomain: (NSString *) domain
{
NSString *uid;
uid = [theID hasPrefix: @"@"] ? [theID substringFromIndex: 1] : theID;
return [SOGoGroup groupWithValue: uid
andSourceSelector: @selector (lookupGroupEntryByUID:)];
andSourceSelector: @selector (lookupGroupEntryByUID:)
inDomain: domain];
}
+ (id) groupWithEmail: (NSString *) theEmail
inDomain: (NSString *) domain
{
return [SOGoGroup groupWithValue: theEmail
andSourceSelector: @selector (lookupGroupEntryByEmail:)];
andSourceSelector: @selector (lookupGroupEntryByEmail:)
inDomain: domain];
}
//
@@ -109,10 +113,11 @@
//
+ (id) groupWithValue: (NSString *) theValue
andSourceSelector: (SEL) theSelector
inDomain: (NSString *) domain
{
NSArray *allSources;
NGLdapEntry *entry;
LDAPSource *source;
NSObject <SOGoSource> *source;
id o;
int i;
@@ -122,7 +127,8 @@
if (!theValue)
return nil;
allSources = [[SOGoUserManager sharedUserManager] sourceIDs];
allSources = [[SOGoUserManager sharedUserManager]
sourceIDsInDomain: domain];
entry = nil;
o = nil;
@@ -156,8 +162,8 @@
[classes containsObject: @"posixGroup"])
{
o = [[self alloc] initWithIdentifier: theValue
source: source
entry: entry];
source: source
entry: entry];
AUTORELEASE(o);
}
}
+34
View File
@@ -0,0 +1,34 @@
/* SOGoLDAPDefaults.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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 SOGOLDAPDEFAULTS_H
#define SOGOLDAPDEFAULTS_H
@protocol SOGoLDAPDefaults
- (int) ldapQueryLimit;
- (int) ldapQueryTimeout;
- (NSString *) ldapContactInfoAttribute;
@end
#endif /* SOGOLDAPDEFAULTS_H */
@@ -1,4 +1,4 @@
/* SOGoLDAPUserDefaultsBootstrap.m - this file is part of $PROJECT_NAME_HERE$
/* SOGoLDAPUserDefaultsBootstrap.m - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
@@ -20,8 +20,6 @@
* Boston, MA 02111-1307, USA.
*/
#import <stdio.h>
#import "SOGoLDAPUserDefaults.h"
void
+7 -1
View File
@@ -23,10 +23,14 @@
#ifndef SOGOMAILER_H
#define SOGOMAILER_H
#import <Foundation/NSObject.h>
@class NSArray;
@class NSException;
@class NSString;
@class SOGoDomainDefaults;
@protocol NGMimePart;
@interface SOGoMailer : NSObject
@@ -35,7 +39,9 @@
NSString *smtpServer;
}
+ (id) sharedMailer;
+ (SOGoMailer *) mailerWithDomainDefaults: (SOGoDomainDefaults *) dd;
- (id) initWithDomainDefaults: (SOGoDomainDefaults *) dd;
- (NSException *) sendMailData: (NSData *) data
toRecipients: (NSArray *) recipients
+16 -47
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGExtensions/NSObject+Logs.h>
@@ -33,65 +32,35 @@
#import <NGMime/NGMimePartGenerator.h>
#import "NSString+Utilities.h"
#import "SOGoMailer.h"
#import "SOGoDomainDefaults.h"
#import "SOGoSystemDefaults.h"
#define defaultMailingMechanism @"sendmail"
#define defaultSMTPServer @"localhost"
#import "SOGoMailer.h"
@implementation SOGoMailer
+ (id) sharedMailer
+ (SOGoMailer *) mailerWithDomainDefaults: (SOGoDomainDefaults *) dd
{
static id sharedMailer = nil;
return [[self alloc] initWithDomainDefaults: dd];
}
if (!sharedMailer)
sharedMailer = [self new];
- (id) initWithDomainDefaults: (SOGoDomainDefaults *) dd
{
if ((self = [self init]))
{
ASSIGN (mailingMechanism, [dd mailingMechanism]);
ASSIGN (smtpServer, [dd smtpServer]);
}
return sharedMailer;
return self;
}
- (id) init
{
NSUserDefaults *ud;
if ((self = [super init]))
{
ud = [NSUserDefaults standardUserDefaults];
mailingMechanism = [ud stringForKey: @"SOGoMailingMechanism"];
if (mailingMechanism)
{
if (!([mailingMechanism isEqualToString: @"sendmail"]
|| [mailingMechanism isEqualToString: @"smtp"]))
{
[self logWithFormat: @"mechanism '%@' is invalid and"
@" should be set to 'sendmail' or 'smtp' instead",
mailingMechanism];
[self logWithFormat: @"falling back to default '%@' mechanism",
defaultMailingMechanism];
mailingMechanism = defaultMailingMechanism;
}
}
else
{
[self logWithFormat: @"default mailing mechanism set to '%@'",
defaultMailingMechanism];
mailingMechanism = defaultMailingMechanism;
}
[mailingMechanism retain];
if ([mailingMechanism isEqualToString: @"smtp"])
{
smtpServer = [ud stringForKey: @"SOGoSMTPServer"];
if (!smtpServer)
{
[self logWithFormat: @"default smtp server set to '%@'",
defaultSMTPServer];
smtpServer = defaultSMTPServer;
}
[smtpServer retain];
}
else
smtpServer = nil;
mailingMechanism = nil;
smtpServer = nil;
}
return self;
+28 -44
View File
@@ -28,7 +28,6 @@
#import <Foundation/NSFileManager.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
@@ -58,18 +57,17 @@
#import "NSObject+Utilities.h"
#import "NSString+Utilities.h"
#import "SOGoCache.h"
#import "SOGoDomainDefaults.h"
#import "SOGoPermissions.h"
#import "SOGoSystemDefaults.h"
#import "SOGoUser.h"
#import "SOGoUserDefaults.h"
#import "SOGoUserFolder.h"
#import "SOGoWebDAVAclManager.h"
#import "SOGoWebDAVValue.h"
#import "SOGoObject.h"
static BOOL kontactGroupDAV = YES;
static BOOL sendACLAdvisories = NO;
static BOOL useRelativeURLs = NO;
static NSDictionary *reportMap = nil;
static NSMutableDictionary *setterMap = nil;
static NSMutableDictionary *getterMap = nil;
@@ -172,15 +170,9 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
+ (void) initialize
{
NSUserDefaults *ud;
NSString *filename;
NSBundle *bundle;
ud = [NSUserDefaults standardUserDefaults];
kontactGroupDAV = ![ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"];
sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"];
useRelativeURLs = [ud boolForKey: @"WOUseRelativeURLs"];
if (!reportMap)
{
bundle = [NSBundle bundleForClass: self];
@@ -941,23 +933,6 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
return nil; /* one etag matches, so continue with request */
}
/* hack for Kontact 3.4 */
if (kontactGroupDAV) {
WEClientCapabilities *cc;
cc = [[(WOContext *)_ctx request] clientCapabilities];
if ([[cc userAgentType] isEqualToString:@"Konqueror"]) {
if ([cc majorVersion] == 3 && [cc minorVersion] == 4) {
[self logWithFormat:
@"WARNING: applying Kontact 3.4 GroupDAV hack"
@" - etag check is disabled!"
@" (can be enabled using 'ZSDisableKontact34GroupDAVHack')"];
return nil;
}
}
}
// TODO: we might want to return the davEntityTag in the response
[self debugWithFormat:@"etag '%@' does not match: %@", etag,
[etags componentsJoinedByString:@","]];
@@ -1041,13 +1016,15 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
- (BOOL) addUserInAcls: (NSString *) uid
{
BOOL result;
SOGoDomainDefaults *dd;
if ([uid length]
&& ![uid isEqualToString: [self ownerInContext: nil]])
{
[self setRoles: [self aclsForUser: uid]
forUser: uid];
if (sendACLAdvisories)
dd = [[context activeUser] domainDefaults];
if ([dd aclSendEMailNotifications])
[self sendACLAdditionAdvisoryToUser: uid];
result = YES;
}
@@ -1060,11 +1037,13 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
- (BOOL) removeUserFromAcls: (NSString *) uid
{
BOOL result;
SOGoDomainDefaults *dd;
if ([uid length])
{
[self removeAclsForUsers: [NSArray arrayWithObject: uid]];
if (sendACLAdvisories)
dd = [[context activeUser] domainDefaults];
if ([dd aclSendEMailNotifications])
[self sendACLRemovalAdvisoryToUser: uid];
result = YES;
}
@@ -1110,12 +1089,12 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
toUser: (NSString *) uid
{
NSString *language, *pageName;
SOGoUser *user;
SOGoUserDefaults *userDefaults;
SOGoACLAdvisory *page;
WOApplication *app;
user = [SOGoUser userWithLogin: uid roles: nil];
language = [user language];
userDefaults = [[SOGoUser userWithLogin: uid roles: nil] userDefaults];
language = [userDefaults language];
pageName = [NSString stringWithFormat: @"SOGoACL%@%@Advisory",
language, template];
@@ -1190,10 +1169,12 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
- (NSString *) davURLAsString
{
NSURL *davURL;
SOGoSystemDefaults *sd;
davURL = [self davURL];
sd = [SOGoSystemDefaults sharedSystemDefaults];
return (useRelativeURLs ? [davURL path] : [davURL absoluteString]);
return ([sd useRelativeURLs] ? [davURL path] : [davURL absoluteString]);
}
- (NSURL *) soURL
@@ -1250,19 +1231,22 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
NSMutableArray *languages;
NSArray *browserLanguages;
NSString *language;
NSUserDefaults *ud;
SOGoUser *user;
#warning the purpose of this method needs to be reviewed
languages = [NSMutableArray array];
language = [[context activeUser] language];
[languages addObject: language];
browserLanguages = [[context request] browserLanguages];
[languages addObjectsFromArray: browserLanguages];
ud = [NSUserDefaults standardUserDefaults];
language = [ud stringForKey: @"SOGoDefaultLanguage"];
if (language)
[languages addObject: language];
[languages addObject: @"English"];
user = [context activeUser];
if ([user isKindOfClass: [SOGoUser class]])
{
language = [[user userDefaults] language];
[languages addObject: language];
}
else
{
browserLanguages = [[context request] browserLanguages];
[languages addObjectsFromArray: browserLanguages];
}
return languages;
}
+1 -2
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoSecurityManager.h>
@@ -266,7 +265,7 @@ static SoSecurityManager *sm = nil;
- (NSException *) appendSubscribedSources
{
NSArray *subscribedReferences;
NSUserDefaults *settings;
SOGoUserSettings *settings;
NSEnumerator *allKeys;
NSString *currentKey;
NSException *error;
-1
View File
@@ -22,7 +22,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOContext.h>
+39
View File
@@ -0,0 +1,39 @@
/* SOGoSQLUserProfile.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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 SOGOSQLUSERPROFILE_H
#define SOGOSQLUSERPROFILE_H
#import "SOGoUserProfile.h"
@class NSURL;
@class NSString;
@interface SOGoSQLUserProfile : SOGoUserProfile
{
NSString *fieldName;
}
@end
#endif /* SOGOSQLUSERPROFILE_H */
+242
View File
@@ -0,0 +1,242 @@
/* SOGoSQLUserProfile.m - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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 <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSNull+misc.h>
#import <GDLContentStore/GCSChannelManager.h>
#import <GDLContentStore/NSURL+GCS.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLAccess/EOAdaptorContext.h>
#import <GDLAccess/EOAttribute.h>
#import "SOGoSystemDefaults.h"
#import "SOGoSQLUserProfile.h"
static NSURL *tableURL = nil;
static NSString *uidColumnName = @"c_uid";
@implementation SOGoSQLUserProfile
+ (void) initialize
{
NSString *profileURL;
SOGoSystemDefaults *sd;
if (!tableURL)
{
sd = [SOGoSystemDefaults sharedSystemDefaults];
profileURL = [sd profileURL];
if (profileURL)
tableURL = [[NSURL alloc] initWithString: profileURL];
}
}
- (id) init
{
if ((self = [super init]))
{
fieldName = nil;
}
return self;
}
- (void) dealloc
{
[fieldName release];
[super dealloc];
}
- (void) setProfileType: (SOGoUserProfileType) newProfileType
{
if (newProfileType == SOGoUserProfileTypeDefaults)
ASSIGN (fieldName, @"c_defaults");
else if (newProfileType == SOGoUserProfileTypeSettings)
ASSIGN (fieldName, @"c_settings");
else
[self errorWithFormat: @"unknown profile value: %d", newProfileType];
[super setProfileType: newProfileType];
}
- (NSString *) fetchJSONProfileFromDB
{
GCSChannelManager *cm;
EOAdaptorChannel *channel;
NSDictionary *row;
NSException *ex;
NSString *sql, *value;
NSArray *attrs;
value = nil;
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: tableURL];
if (channel)
{
/* generate SQL */
defFlags.ready = YES;
sql = [NSString stringWithFormat: @"SELECT %@ FROM %@ WHERE %@ = '%@'",
fieldName, [tableURL gcsTableName],
uidColumnName, [self uid]];
/* run SQL */
ex = [channel evaluateExpressionX: sql];
if (ex)
[self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
else
{
/* fetch schema */
attrs = [channel describeResults: NO /* don't beautify */];
/* fetch values */
row = [channel fetchAttributes: attrs withZone: NULL];
[channel cancelFetch];
/* the isNew flag depends on the presence of the row in the
database rather than on the existence of the value. */
defFlags.isNew = (row == nil);
value = [row objectForKey: fieldName];
if ([value isNotNull])
/* The following enables the restitution of coded unicode (\U1234)
characters with the Oracle adaptor. */
value = [value stringByReplacingString: @"\\\\"
withString: @"\\"];
else
value = nil; /* we discard any NSNull instance */
}
[cm releaseChannel: channel];
}
else
{
defFlags.ready = NO;
[self errorWithFormat:@"failed to acquire channel for URL: %@",
tableURL];
}
return value;
}
- (NSString *) _sqlJsonRepresentation: (NSString *) jsonRepresentation
{
NSMutableString *sql;
sql = [jsonRepresentation mutableCopy];
[sql autorelease];
[sql replaceString: @"\\" withString: @"\\\\"];
[sql replaceString: @"'" withString: @"''"];
return sql;
}
- (NSString *) generateSQLForInsert: (NSString *) jsonRepresentation
{
NSString *sql;
if ([jsonRepresentation length])
sql = [NSString stringWithFormat: (@"INSERT INTO %@"
@" (%@, %@)"
@" VALUES ('%@', '%@')"),
[tableURL gcsTableName], uidColumnName, fieldName,
[self uid],
[self _sqlJsonRepresentation: jsonRepresentation]];
else
sql = nil;
return sql;
}
- (NSString *) generateSQLForUpdate: (NSString *) jsonRepresentation
{
NSString *sql;
if ([jsonRepresentation length])
sql = [NSString stringWithFormat: (@"UPDATE %@"
@" SET %@ = '%@'"
@" WHERE %@ = '%@'"),
[tableURL gcsTableName],
fieldName,
[self _sqlJsonRepresentation: jsonRepresentation],
uidColumnName, [self uid]];
else
sql = nil;
return sql;
}
- (BOOL) storeJSONProfileInDB: (NSString *) jsonRepresentation
{
GCSChannelManager *cm;
EOAdaptorChannel *channel;
EOAdaptorContext *context;
NSException *ex;
NSString *sql;
BOOL rc;
rc = NO;
sql = ((defFlags.isNew)
? [self generateSQLForInsert: jsonRepresentation]
: [self generateSQLForUpdate: jsonRepresentation]);
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: tableURL];
if (channel)
{
context = [channel adaptorContext];
if ([context beginTransaction])
{
defFlags.ready = YES;
ex = [channel evaluateExpressionX:sql];
if (ex)
{
[self errorWithFormat: @"could not run SQL '%@': %@", sql, ex];
[context rollbackTransaction];
}
else
{
rc = YES;
defFlags.modified = NO;
defFlags.isNew = NO;
[context commitTransaction];
}
[cm releaseChannel: channel];
}
else
{
defFlags.ready = NO;
[cm releaseChannel: channel immediately: YES];
}
}
else
{
defFlags.ready = NO;
[self errorWithFormat: @"failed to acquire channel for URL: %@",
tableURL];
}
return rc;
}
@end
+6 -2
View File
@@ -30,9 +30,13 @@
@protocol SOGoSource
+ (id) sourceFromUDSource: (NSDictionary *) udSource;
+ (id) sourceFromUDSource: (NSDictionary *) udSource
inDomain: (NSString *) domain;
- (id) initFromUDSource: (NSDictionary *) udSource;
- (id) initFromUDSource: (NSDictionary *) udSource
inDomain: (NSString *) domain;
- (NSString *) domain;
- (BOOL) checkLogin: (NSString *) login
andPassword: (NSString *) password;
+61
View File
@@ -0,0 +1,61 @@
/* SOGoSystemDefaults.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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 SOGOSYSTEMDEFAULTS_H
#define SOGOSYSTEMDEFAULTS_H
#import <SOGo/SOGoDomainDefaults.h>
@interface SOGoSystemDefaults : SOGoDomainDefaults
+ (SOGoSystemDefaults *) sharedSystemDefaults;
- (NSArray *) domainIds;
- (BOOL) crashOnSessionCreate;
- (BOOL) debugRequests;
- (BOOL) debugLeaks;
- (int) vmemLimit;
- (BOOL) trustProxyAuthentication;
- (BOOL) useRelativeURLs;
- (NSString *) faviconRelativeURL;
- (NSString *) zipPath;
- (int) port;
- (int) workers;
- (NSString *) logFile;
- (NSString *) pidFile;
- (NSTimeInterval) cacheCleanupInterval;
- (NSString *) memcachedHost;
- (BOOL) userCanChangePassword;
- (BOOL) uixAdditionalPreferences;
- (BOOL) uixDebugEnabled;
- (NSArray *) supportedLanguages;
- (NSString *) loginSuffix;
@end
#endif /* SOGOSYSTEMDEFAULTS_H */
+274
View File
@@ -0,0 +1,274 @@
/* SOGoSystemDefaults.m - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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 <dlfcn.h>
#import <unistd.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGExtensions/NSObject+Logs.h>
#import "NSDictionary+Utilities.h"
#import "SOGoStartupLogger.h"
#define NEEDS_DEFAULTS_SOURCE_INTERNAL 1
#import "SOGoSystemDefaults.h"
@implementation SOGoSystemDefaults
#if defined(LDAP_CONFIG)
#import <SOGo/SOGoLDAPUserDefaults.h>
#endif
typedef void (*NSUserDefaultsInitFunction) ();
#define DIR_SEP "/"
static void
BootstrapNSUserDefaults ()
{
char *filename;
NSUserDefaultsInitFunction SOGoNSUserDefaultsBootstrap;
void *handle;
filename = SOGO_LIBDIR DIR_SEP "libSOGoNSUserDefaults.so.1";
handle = dlopen (filename, RTLD_NOW | RTLD_GLOBAL);
if (handle)
{
SOGoNSUserDefaultsBootstrap = dlsym (handle,
"SOGoNSUserDefaultsBootstrap");
if (SOGoNSUserDefaultsBootstrap)
SOGoNSUserDefaultsBootstrap ();
}
}
+ (void) injectSOGoDefaults: (NSUserDefaults *) ud
{
NSBundle *bundle;
NSDictionary *baseSOGoDefaults;
NSString *filename;
bundle = [NSBundle bundleForClass: self];
filename = [bundle pathForResource: @"SOGoDefaults" ofType: @"plist"];
if (filename
&& [[NSFileManager defaultManager] fileExistsAtPath: filename])
{
baseSOGoDefaults
= [[NSDictionary alloc] initWithContentsOfFile: filename];
if (baseSOGoDefaults)
{
[ud registerDefaults: baseSOGoDefaults];
[baseSOGoDefaults autorelease];
}
else
[bundle errorWithFormat: @"Unable to deserialize SOGoDefaults.plist"];
}
else
[bundle errorWithFormat: @"SOGoDefaults.plist not found"];
}
+ (void) prepareUserDefaults
{
NSString *redirectURL;
NSDictionary *domain;
NSUserDefaults *ud;
SOGoStartupLogger *logger;
logger = [SOGoStartupLogger sharedLogger];
ud = [NSUserDefaults standardUserDefaults];
domain = [ud persistentDomainForName: @"sogod"];
if (![domain count])
{
domain = [ud persistentDomainForName: @"sogod-0.9"];
if ([domain count])
{
[logger logWithFormat: @"migrating user defaults from sogod-0.9"];
[ud setPersistentDomain: domain forName: @"sogod"];
[ud removePersistentDomainForName: @"sogod-0.9"];
[ud synchronize];
}
else
[logger warnWithFormat: @"No configuration found."
@" SOGo will not work properly."];
}
[self injectSOGoDefaults: ud];
redirectURL = [ud stringForKey: @"WOApplicationRedirectURL"];
if (redirectURL)
{
[logger warnWithFormat:
@"Using obsolete 'WOApplicationRedirectURL' user default."];
[logger warnWithFormat:
@" Please configure the use of the x-webobjects-XXX headers"
@" with your webserver (see sample files)."];
if ([redirectURL hasSuffix: @"/"])
[ud setObject: [redirectURL substringToIndex: [redirectURL length] - 1]
forKey: @"WOApplicationRedirectURL"];
}
}
+ (void) initialize
{
BootstrapNSUserDefaults ();
[self prepareUserDefaults];
}
+ (SOGoSystemDefaults *) sharedSystemDefaults
{
static SOGoSystemDefaults *sharedSystemDefaults = nil;
NSUserDefaults *ud;
if (!sharedSystemDefaults)
{
ud = [NSUserDefaults standardUserDefaults];
sharedSystemDefaults = [self defaultsSourceWithSource: ud
andParentSource: nil];
[sharedSystemDefaults retain];
}
return sharedSystemDefaults;
}
- (BOOL) migrate
{
static NSDictionary *migratedKeys = nil;
if (!migratedKeys)
{
migratedKeys = [NSDictionary dictionaryWithObjectsAndKeys:
@"SOGoProfileURL", @"AgenorProfileURL",
@"SOGoTimeZone", @"SOGoServerTimeZone",
nil];
[migratedKeys retain];
}
return ([self migrateOldDefaultsWithDictionary: migratedKeys]
| [super migrate]);
}
- (NSArray *) domainIds
{
return [[self dictionaryForKey: @"domains"] allKeys];
}
/* System-level only */
- (BOOL) crashOnSessionCreate
{
return [self boolForKey: @"SOGoCrashOnSessionCreate"];
}
- (BOOL) debugRequests
{
return [self boolForKey: @"SOGoDebugRequests"];
}
- (BOOL) debugLeaks;
{
return [self boolForKey: @"SOGoDebugLeaks"];
}
- (int) vmemLimit
{
return [self integerForKey: @"SxVMemLimit"];
}
- (BOOL) trustProxyAuthentication;
{
return [self boolForKey: @"SOGoTrustProxyAuthentication"];
}
- (BOOL) useRelativeURLs
{
return [self boolForKey: @"WOUseRelativeURLs"];
}
- (NSString *) faviconRelativeURL
{
return [self stringForKey: @"SOGoFaviconRelativeURL"];
}
- (NSString *) zipPath
{
return [self stringForKey: @"SOGoZipPath"];
}
- (int) port
{
return [self integerForKey: @"WOPort"];
}
- (int) workers
{
return [self integerForKey: @"WOWorkersCount"];
}
- (NSString *) logFile
{
return [self stringForKey: @"WOLogFile"];
}
- (NSString *) pidFile
{
return [self stringForKey: @"WOPidFile"];
}
- (NSTimeInterval) cacheCleanupInterval
{
return [self floatForKey: @"SOGoCacheCleanupInterval"];
}
- (NSString *) memcachedHost
{
return [self stringForKey: @"SOGoMemcachedHost"];
}
- (BOOL) uixDebugEnabled
{
return [self boolForKey: @"SOGoUIxDebugEnabled"];
}
- (NSArray *) supportedLanguages
{
return [self stringArrayForKey: @"SOGoSupportedLanguages"];
}
- (BOOL) userCanChangePassword
{
return [self boolForKey: @"SOGoUIxUserCanChangePassword"];
}
- (BOOL) uixAdditionalPreferences
{
return [self boolForKey: @"SOGoUIxAdditionalPreferences"];
}
- (NSString *) loginSuffix
{
return [self stringForKey: @"SOGoLoginSuffix"];
}
@end
+17 -34
View File
@@ -40,40 +40,41 @@
@class NSMutableArray;
@class NSMutableDictionary;
@class NSString;
@class NSTimeZone;
@class NSURL;
@class NSUserDefaults;
@class WOContext;
@class SOGoAppointmentFolder;
@class SOGoAppointmentFolders;
@class SOGoDateFormatter;
@class SOGoDomainDefaults;
@class SOGoUserDefaults;
@class SOGoUserFolder;
@class SOGoUserProfile;
@class SOGoUserSettings;
extern NSString *SOGoWeekStartJanuary1;
extern NSString *SOGoWeekStartFirst4DayWeek;
extern NSString *SOGoWeekStartFirstFullWeek;
// @interface SoUser (SOGoExtension)
@interface SoUser (SOGoExtension)
// - (NSString *) language;
- (NSString *) language;
@end
// @end
@interface SOGoUser : SoUser
{
SOGoUserDefaults *_defaults, *_settings;
SOGoUserDefaults *_defaults;
SOGoDomainDefaults *_domainDefaults;
SOGoUserSettings *_settings;
SOGoUserFolder *homeFolder;
NSString *currentPassword;
NSString *domainId;
NSString *language;
NSArray *allEmails;
NSArray *mailAccounts;
NSString *cn;
BOOL propagateCache;
}
+ (NSString *) language;
// + (NSString *) language;
+ (SOGoUser *) userWithLogin: (NSString *) newLogin;
@@ -94,32 +95,23 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (NSString *) currentPassword;
/* properties */
- (NSString *) domain;
- (NSArray *) allEmails;
- (BOOL) hasEmail: (NSString *) email;
- (NSString *) systemEmail;
- (NSString *) cn;
- (NSURL *) freeBusyURL;
- (SOGoDateFormatter *) dateFormatterInContext: (WOContext *) context;
/* defaults */
- (NSUserDefaults *) userDefaults;
- (NSUserDefaults *) userSettings;
- (SOGoUserDefaults *) userDefaults;
- (SOGoDomainDefaults *) domainDefaults;
- (SOGoUserSettings *) userSettings;
- (void) invalidateLanguage;
- (NSString *) language;
- (NSTimeZone *) timeZone;
- (NSTimeZone *) serverTimeZone;
- (unsigned int) firstDayOfWeek;
- (NSCalendarDate *) firstDayOfWeekForDate: (NSCalendarDate *) date;
- (unsigned int) dayOfWeekForDate: (NSCalendarDate *) date;
- (unsigned int) dayStartHour;
- (unsigned int) dayEndHour;
- (NSString *) timeFormat;
- (NSCalendarDate *) firstWeekOfYearForDate: (NSCalendarDate *) date;
- (unsigned int) weekNumberForDate: (NSCalendarDate *) date;
@@ -128,13 +120,6 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (NSArray *) allIdentities;
- (NSDictionary *) primaryIdentity;
- (NSMutableDictionary *) defaultIdentity;
- (NSString *) messageForwarding;
- (NSString *) signature;
- (NSString *) replyPlacement;
- (NSString *) signaturePlacement;
- (void) saveMailAccounts;
- (BOOL) isSuperUser;
@@ -152,8 +137,6 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (NSArray *) rolesForObject: (NSObject *) object
inContext: (WOContext *) context;
- (void) migrateSignature;
@end
#endif /* __SOGoUser_H__ */
+184 -460
View File
@@ -26,7 +26,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSNull.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSURL.h>
#import <NGObjWeb/WOApplication.h>
@@ -40,200 +39,52 @@
#import "NSArray+Utilities.h"
#import "SOGoCache.h"
#import "SOGoDateFormatter.h"
#import "SOGoDomainDefaults.h"
#import "SOGoObject.h"
#import "SOGoPermissions.h"
#import "SOGoSystemDefaults.h"
#import "SOGoUserDefaults.h"
#import "SOGoUserFolder.h"
#import "SOGoUserManager.h"
#import "SOGoUserProfile.h"
#import "SOGoUserSettings.h"
#import "../../Main/SOGo.h"
#import "SOGoUser.h"
static NSTimeZone *serverTimeZone = nil;
static NSString *fallbackIMAP4Server = nil;
static BOOL fallbackIsConfigured = NO;
static NSString *defaultLanguage = nil;
static NSString *defaultReplyPlacement = nil;
static NSString *defaultSignaturePlacement = nil;
static NSString *defaultMessageForwarding = nil;
static NSString *defaultMessageCheck = nil;
static NSString *defaultTimeFormat = nil;
static NSArray *superUsernames = nil;
static NSURL *SOGoProfileURL = nil;
// static BOOL acceptAnyUser = NO;
static int sogoFirstDayOfWeek = -1;
static int defaultDayStartTime = -1;
static int defaultDayEndTime = -1;
static Class SOGoUserDefaultsKlass = Nil;
NSString *SOGoWeekStartJanuary1 = @"January1";
NSString *SOGoWeekStartFirst4DayWeek = @"First4DayWeek";
NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
@interface NSObject (SOGoRoles)
- (NSArray *) rolesOfUser: (NSString *) uid;
@end
@implementation SoUser (SOGoExtension)
- (NSString *) language
- (SOGoDomainDefaults *) userDefaults
{
return [SOGoUser language];
return [SOGoSystemDefaults sharedSystemDefaults];
}
- (SOGoDomainDefaults *) domainDefaults
{
return [SOGoSystemDefaults sharedSystemDefaults];
}
@end
@implementation SOGoUser
static int
_timeValue (NSString *key)
{
int i, time;
// + (NSString *) language
// {
// NSArray *bLanguages;
// WOContext *context;
// NSString *lng;
if (key && [key length] > 0)
{
i = [key rangeOfString: @":"].location;
if (i != NSNotFound)
time = [[key substringToIndex: i] intValue];
else
time = [key intValue];
}
else
time = -1;
return time;
}
// context = [[WOApplication application] context];
// bLanguages = [[context request] browserLanguages];
// if ([bLanguages count] > 0)
// lng = [bLanguages objectAtIndex: 0];
+ (void) initialize
{
NSString *tzName;
NSUserDefaults *ud;
NSString *profileURL;
// if (![lng length])
// lng = defaultLanguage;
ud = [NSUserDefaults standardUserDefaults];
if (!serverTimeZone)
{
tzName = [ud stringForKey: @"SOGoServerTimeZone"];
if (!tzName)
tzName = @"UTC";
serverTimeZone = [NSTimeZone timeZoneWithName: tzName];
[serverTimeZone retain];
}
if (sogoFirstDayOfWeek == -1)
sogoFirstDayOfWeek = [ud integerForKey: @"SOGoFirstDayOfWeek"];
if (defaultDayStartTime == -1)
{
defaultDayStartTime
= _timeValue ([ud stringForKey: @"SOGoDayStartTime"]);
if (defaultDayStartTime == -1)
defaultDayStartTime = 8;
}
if (defaultDayEndTime == -1)
{
defaultDayEndTime
= _timeValue ([ud stringForKey: @"SOGoDayEndTime"]);
if (defaultDayEndTime == -1)
defaultDayEndTime = 18;
}
if (!SOGoProfileURL)
{
profileURL = [ud stringForKey: @"SOGoProfileURL"];
if (!profileURL)
{
profileURL = [ud stringForKey: @"AgenorProfileURL"];
if (profileURL)
{
[ud setObject: profileURL forKey: @"SOGoProfileURL"];
[ud removeObjectForKey: @"AgenorProfileURL"];
[ud synchronize];
[self warnWithFormat: @"the user defaults key 'AgenorProfileURL'"
@" was renamed to 'SOGoProfileURL'"];
}
}
if (profileURL)
SOGoProfileURL = [[NSURL alloc] initWithString: profileURL];
}
if (!fallbackIMAP4Server)
ASSIGN (fallbackIMAP4Server,
[ud stringForKey: @"SOGoFallbackIMAP4Server"]);
if (fallbackIMAP4Server)
fallbackIsConfigured = YES;
else
{
[self warnWithFormat:
@"no server specified for SOGoFallbackIMAP4Server,"
@" value set to 'localhost'"];
fallbackIMAP4Server = @"localhost";
}
if (!defaultLanguage)
{
ASSIGN (defaultLanguage, [ud stringForKey: @"SOGoDefaultLanguage"]);
if (!defaultLanguage)
ASSIGN (defaultLanguage, @"English");
}
if (!defaultReplyPlacement)
{
ASSIGN (defaultReplyPlacement, [ud stringForKey: @"SOGoMailReplyPlacement"]);
if (!defaultReplyPlacement)
ASSIGN (defaultReplyPlacement, @"below");
}
if (!defaultSignaturePlacement)
{
ASSIGN (defaultSignaturePlacement, [ud stringForKey: @"SOGoMailSignaturePlacement"]);
if (!defaultSignaturePlacement)
ASSIGN (defaultSignaturePlacement, @"below");
}
if (!defaultMessageForwarding)
{
ASSIGN (defaultMessageForwarding, [ud stringForKey: @"SOGoMailMessageForwarding"]);
if (!defaultMessageForwarding)
ASSIGN (defaultMessageForwarding, @"inline");
}
if (!defaultMessageCheck)
{
ASSIGN (defaultMessageCheck, [ud stringForKey: @"SOGoMailMessageCheck"]);
if (!defaultMessageCheck)
ASSIGN (defaultMessageCheck, @"manually");
}
if (!defaultTimeFormat)
{
ASSIGN (defaultTimeFormat, [ud stringForKey: @"SOGoTimeFormat"]);
if (!defaultTimeFormat)
ASSIGN (defaultTimeFormat, @"%H:00");
}
if (!superUsernames)
ASSIGN (superUsernames, [ud arrayForKey: @"SOGoSuperUsernames"]);
// acceptAnyUser = ([[ud stringForKey: @"SOGoAuthentificationMethod"]
// isEqualToString: @"bypass"]);
}
+ (NSString *) language
{
NSArray *bLanguages;
WOContext *context;
NSString *lng;
context = [[WOApplication application] context];
bLanguages = [[context request] browserLanguages];
if ([bLanguages count] > 0)
lng = [bLanguages objectAtIndex: 0];
if (![lng length])
lng = defaultLanguage;
return lng;
}
+ (NSString *) fallbackIMAP4Server
{
return fallbackIMAP4Server;
}
// return lng;
// }
+ (SOGoUser *) userWithLogin: (NSString *) newLogin
{
@@ -257,7 +108,7 @@ _timeValue (NSString *key)
user = [cache userNamed: newLogin];
if (!user)
{
user = [[self alloc] initWithLogin: newLogin roles: newRoles trust: b];
user = [[self alloc] initWithLogin: newLogin roles: newRoles trust: b];
if (user)
{
[user autorelease];
@@ -302,6 +153,11 @@ _timeValue (NSString *key)
allEmails = nil;
currentPassword = nil;
cn = nil;
_defaults = nil;
_domainDefaults = nil;
_settings = nil;
allEmails = nil;
mailAccounts = nil;
}
}
else
@@ -316,8 +172,10 @@ _timeValue (NSString *key)
- (void) dealloc
{
[_defaults release];
[_domainDefaults release];
[_settings release];
[allEmails release];
[mailAccounts release];
[currentPassword release];
[cn release];
[language release];
@@ -326,12 +184,12 @@ _timeValue (NSString *key)
- (void) setPrimaryRoles: (NSArray *) newRoles
{
ASSIGN(roles, newRoles);
ASSIGN (roles, newRoles);
}
- (void) setCurrentPassword: (NSString *) newPassword
{
ASSIGN(currentPassword, newPassword);
ASSIGN (currentPassword, newPassword);
}
- (NSString *) currentPassword
@@ -363,6 +221,11 @@ _timeValue (NSString *key)
}
/* properties */
- (NSString *) domain
{
return [self _fetchFieldForUser: @"c_domain"];
}
- (NSArray *) allEmails
{
if (!allEmails)
@@ -411,197 +274,158 @@ _timeValue (NSString *key)
return defaultIdentity;
}
- (void) saveMailAccounts
{
BOOL doSave;
doSave = YES;
if (!fallbackIsConfigured)
{
[self logWithFormat: @"'SOGoFallbackIMAP4Server' is not set"];
doSave = NO;
}
if (![SOGoUserManager defaultMailDomainIsConfigured])
{
[self logWithFormat: @"'SOGoDefaultMailDomain' is not set"];
doSave = NO;
}
doSave = NO;
if (doSave)
[[self userDefaults] setObject: [self mailAccounts]
forKey: @"MailAccounts"];
else
[self logWithFormat: @"saving mail accounts is disabled until the"
@" variable(s) mentionned above are configured"];
}
- (NSURL *) freeBusyURL
{
return nil;
}
- (SOGoDateFormatter *) dateFormatterInContext: (WOContext *) context
{
SOGoDateFormatter *dateFormatter;
NSString *format;
NSUserDefaults *ud;
SOGoUserDefaults *ud;
NSDictionary *locale;
dateFormatter = [SOGoDateFormatter new];
[dateFormatter autorelease];
[dateFormatter setLocale: [[WOApplication application] localeForLanguageNamed: [self language]]];
ud = [self userDefaults];
format = [ud stringForKey: @"ShortDateFormat"];
locale = [[WOApplication application] localeForLanguageNamed: [ud language]];
[dateFormatter setLocale: locale];
format = [ud shortDateFormat];
if (format)
[dateFormatter setShortDateFormat: format];
format = [ud stringForKey: @"LongDateFormat"];
format = [ud longDateFormat];
if (format)
[dateFormatter setLongDateFormat: format];
format = [ud stringForKey: @"TimeFormat"];
format = [ud timeFormat];
if (format)
[dateFormatter setTimeFormat: format];
return dateFormatter;
}
- (NSString *) userDefaultsClassName
{
return @"SOGoUserDefaults";
}
- (NSUserDefaults *) userDefaults
- (SOGoUserDefaults *) userDefaults
{
if (!_defaults)
{
if (!SOGoUserDefaultsKlass)
SOGoUserDefaultsKlass
= NSClassFromString ([self userDefaultsClassName]);
_defaults = [[SOGoUserDefaultsKlass alloc]
initWithTableURL: SOGoProfileURL
uid: login
fieldName: @"c_defaults"];
if (_defaults)
{
[_defaults fetchProfile];
if ([_defaults values])
{
BOOL b;
b = NO;
if (![[_defaults stringForKey: @"MessageCheck"] length])
{
[_defaults setObject: defaultMessageCheck forKey: @"MessageCheck"];
b = YES;
}
if (![[_defaults stringForKey: @"TimeZone"] length])
{
[_defaults setObject: [serverTimeZone name] forKey: @"TimeZone"];
b = YES;
}
if (b)
[_defaults synchronize];
// See explanation in -language
[self invalidateLanguage];
}
}
_defaults = [SOGoUserDefaults defaultsForUser: login
inDomain: [self domain]];
[_defaults retain];
}
//else
// NSLog(@"User defaults cache hit for %@", login);
return (NSUserDefaults *) _defaults;
return _defaults;
}
- (NSUserDefaults *) userSettings
- (SOGoDomainDefaults *) domainDefaults
{
if (!_settings)
NSString *domain;
if (!_domainDefaults)
{
if (!SOGoUserDefaultsKlass)
SOGoUserDefaultsKlass
= NSClassFromString ([self userDefaultsClassName]);
_settings = [[SOGoUserDefaultsKlass alloc]
initWithTableURL: SOGoProfileURL
uid: login
fieldName: @"c_settings"];
if (_settings)
{
[_settings fetchProfile];
// See explanation in -language
[self invalidateLanguage];
}
domain = [self domain];
if ([domain length])
{
_domainDefaults = [SOGoDomainDefaults defaultsForDomain: domain];
if (!_domainDefaults)
{
[self errorWithFormat: @"domain '%@' does not exist!", domain];
_domainDefaults = [SOGoSystemDefaults sharedSystemDefaults];
}
}
else
_domainDefaults = [SOGoSystemDefaults sharedSystemDefaults];
[_domainDefaults retain];
}
//else
// NSLog(@"User settings cache hit for %@", login);
// NSLog(@"User defaults cache hit for %@", login);
return (NSUserDefaults *) _settings;
return _domainDefaults;
}
- (void) invalidateLanguage
{
DESTROY(language);
}
// - (SOGoUserDefaults *) userDefaults
// {
// if (!_defaults)
// {
// [SOGoUserDefaults defaultsForUser: login
// inDomain: [self domainName]]
// if (!SOGoUserProfileKlass)
// SOGoUserProfileKlass
// = NSClassFromString ([self userProfileClassName]);
// _defaults = [SOGoUserProfileKlass
// userProfileWithType: SOGoUserProfileTypeDefaults
// forUID: login];
// if (_defaults)
// {
// [_defaults retain];
// [_defaults fetchProfile];
// if ([_defaults values])
// {
// BOOL b;
// b = NO;
- (NSString *) language
// if (![[_defaults stringForKey: @"MessageCheck"] length])
// {
// [_defaults setObject: defaultMessageCheck forKey: @"MessageCheck"];
// b = YES;
// }
// if (![[_defaults stringForKey: @"TimeZone"] length])
// {
// [_defaults setObject: [serverTimeZone name] forKey: @"TimeZone"];
// b = YES;
// }
// if (b)
// [_defaults synchronize];
// // See explanation in -language
// [self invalidateLanguage];
// }
// }
// }
// //else
// // NSLog(@"User defaults cache hit for %@", login);
// return _defaults;
// }
- (SOGoUserSettings *) userSettings
{
if (![language length])
if (!_settings)
{
language = [[self userDefaults] stringForKey: @"Language"];
// This is a workaround until we handle the connection errors to the db
// in a better way. It enables us to avoid retrieving the userDefaults
// too many times when the DB is down, causing a huge delay.
if (![language length])
language = [SOGoUser language];
[language retain];
_settings = [SOGoUserSettings settingsForUser: login];
[_settings retain];
}
return language;
return _settings;
}
- (NSTimeZone *) timeZone
{
NSTimeZone *userTimeZone;
NSString *timeZoneName;
timeZoneName = [[self userDefaults] stringForKey: @"TimeZone"];
userTimeZone = nil;
// - (void) invalidateLanguage
// {
// DESTROY(language);
// }
if ([timeZoneName length] > 0)
userTimeZone = [NSTimeZone timeZoneWithName: timeZoneName];
if (!userTimeZone)
userTimeZone = serverTimeZone;
return userTimeZone;
}
// - (NSString *) language
// {
// if (![language length])
// {
// language = [[self userDefaults] stringForKey: @"Language"];
// // This is a workaround until we handle the connection errors to the db
// // in a better way. It enables us to avoid retrieving the userDefaults
// // too many times when the DB is down, causing a huge delay.
// if (![language length])
// language = [SOGoUser language];
- (NSTimeZone *) serverTimeZone
{
return serverTimeZone;
}
// [language retain];
// }
- (unsigned int) firstDayOfWeek
{
unsigned int firstDayOfWeek;
NSNumber *value;
value = [[self userDefaults] objectForKey: @"WeekStartDay"];
if (value)
firstDayOfWeek = [value unsignedIntValue];
else
firstDayOfWeek = sogoFirstDayOfWeek;
return firstDayOfWeek;
}
// return language;
// }
- (NSCalendarDate *) firstDayOfWeekForDate: (NSCalendarDate *) date
{
int offset;
NSCalendarDate *firstDay;
offset = ([self firstDayOfWeek] - [date dayOfWeek]);
offset = [[self userDefaults] firstDayOfWeek] - [date dayOfWeek];
if (offset > 0)
offset -= 7;
@@ -614,7 +438,7 @@ _timeValue (NSString *key)
{
unsigned int offset, baseDayOfWeek, dayOfWeek;
offset = [self firstDayOfWeek];
offset = [[self userDefaults] firstDayOfWeek];
baseDayOfWeek = [date dayOfWeek];
if (offset > baseDayOfWeek)
baseDayOfWeek += 7;
@@ -624,46 +448,13 @@ _timeValue (NSString *key)
return dayOfWeek;
}
- (unsigned int) dayStartHour
{
int limit;
limit = _timeValue ([[self userDefaults] stringForKey: @"DayStartTime"]);
if (limit == -1)
limit = defaultDayStartTime;
return limit;
}
- (unsigned int) dayEndHour
{
int limit;
limit = _timeValue ([[self userDefaults] stringForKey: @"DayEndTime"]);
if (limit == -1)
limit = defaultDayEndTime;
return limit;
}
- (NSString *) timeFormat
{
NSString *timeFormat;
timeFormat = [[self userDefaults] stringForKey: @"TimeFormat"];
if (!timeFormat)
timeFormat = defaultTimeFormat;
return timeFormat;
}
- (NSCalendarDate *) firstWeekOfYearForDate: (NSCalendarDate *) date
{
NSString *firstWeekRule;
NSCalendarDate *januaryFirst, *firstWeek;
unsigned int dayOfWeek;
firstWeekRule = [[self userDefaults] objectForKey: @"FirstWeek"];
firstWeekRule = [[self userDefaults] firstWeekOfYear];
januaryFirst = [NSCalendarDate dateWithYear: [date yearOfCommonEra]
month: 1 day: 1 hour: 0 minute: 0 second: 0
@@ -712,61 +503,52 @@ _timeValue (NSString *key)
}
/* mail */
- (NSArray *) _prepareDefaultMailAccounts
- (NSArray *) mailAccounts
{
NSMutableDictionary *mailAccount, *identity;
NSMutableArray *identities, *mailAccounts;
NSMutableArray *identities;
NSString *name, *fullName, *imapLogin, *imapServer;
NSArray *mails;
unsigned int count, max;
imapLogin = [[SOGoUserManager sharedUserManager] getImapLoginForUID: login];
imapServer = [self _fetchFieldForUser: @"c_imaphostname"];
if (!imapServer)
imapServer = fallbackIMAP4Server;
mailAccount = [NSMutableDictionary dictionary];
name = [NSString stringWithFormat: @"%@@%@",
imapLogin, imapServer];
[mailAccount setObject: imapLogin forKey: @"userName"];
[mailAccount setObject: imapServer forKey: @"serverName"];
[mailAccount setObject: name forKey: @"name"];
identities = [NSMutableArray array];
mails = [self allEmails];
max = [mails count];
if (max > 1)
max--;
for (count = 0; count < max; count++)
{
identity = [NSMutableDictionary dictionary];
fullName = [self cn];
if (![fullName length])
fullName = login;
[identity setObject: fullName forKey: @"fullName"];
[identity setObject: [mails objectAtIndex: count] forKey: @"email"];
[identities addObject: identity];
}
[[identities objectAtIndex: 0] setObject: [NSNumber numberWithBool: YES]
forKey: @"isDefault"];
[mailAccount setObject: identities forKey: @"identities"];
mailAccounts = [NSMutableArray array];
[mailAccounts addObject: mailAccount];
return mailAccounts;
}
- (NSArray *) mailAccounts
{
NSUserDefaults *ud;
NSArray *mailAccounts;
ud = [self userDefaults];
mailAccounts = [ud objectForKey: @"MailAccounts"];
if (!mailAccounts)
mailAccounts = [self _prepareDefaultMailAccounts];
{
imapLogin = [[SOGoUserManager sharedUserManager]
getImapLoginForUID: login];
imapServer = [self _fetchFieldForUser: @"c_imaphostname"];
if (!imapServer)
imapServer = [[self domainDefaults] imapServer];
mailAccount = [NSMutableDictionary dictionary];
name = [NSString stringWithFormat: @"%@@%@",
imapLogin, imapServer];
[mailAccount setObject: imapLogin forKey: @"userName"];
[mailAccount setObject: imapServer forKey: @"serverName"];
[mailAccount setObject: name forKey: @"name"];
identities = [NSMutableArray array];
mails = [self allEmails];
max = [mails count];
if (max > 1)
max--;
for (count = 0; count < max; count++)
{
identity = [NSMutableDictionary dictionary];
fullName = [self cn];
if (![fullName length])
fullName = login;
[identity setObject: fullName forKey: @"fullName"];
[identity setObject: [mails objectAtIndex: count] forKey: @"email"];
[identities addObject: identity];
}
[[identities objectAtIndex: 0] setObject: [NSNumber numberWithBool: YES]
forKey: @"isDefault"];
[mailAccount setObject: identities forKey: @"identities"];
mailAccounts = [NSArray arrayWithObject: mailAccount];
[mailAccounts retain];
}
return mailAccounts;
}
@@ -861,66 +643,6 @@ _timeValue (NSString *key)
return [[defaultAccount objectForKey: @"identities"] objectAtIndex: 0];
}
- (void) migrateSignature
{
NSString *signature;
NSUserDefaults *ud;
signature = [[self primaryIdentity] objectForKey: @"signature"];
if ([signature length])
{
ud = [self userDefaults];
[ud setObject: signature forKey: @"MailSignature"];
[ud removeObjectForKey: @"MailAccounts"];
[ud synchronize];
}
}
- (NSString *) signature
{
[self migrateSignature];
return [[self userDefaults] stringForKey: @"MailSignature"];
}
- (NSString *) replyPlacement
{
NSString *replyPlacement = [[self userDefaults] stringForKey: @"ReplyPlacement"];
if (!replyPlacement)
replyPlacement = defaultReplyPlacement;
return replyPlacement;
}
- (NSString *) signaturePlacement
{
NSString *signaturePlacement;
if ([[self replyPlacement] isEqualToString: @"below"])
// When replying to an email, if the reply is below the quoted text,
// the signature must also be below the quoted text.
signaturePlacement = @"below";
else
{
signaturePlacement = [[self userDefaults] stringForKey: @"SignaturePlacement"];
if (!signaturePlacement)
signaturePlacement = defaultSignaturePlacement;
}
return signaturePlacement;
}
- (NSString *) messageForwarding
{
NSString *messageForwarding = [[self userDefaults] stringForKey: @"MessageForwarding"];
if (!messageForwarding)
messageForwarding = defaultMessageForwarding;
return messageForwarding;
}
/* folders */
// TODO: those methods should check whether the traversal stack in the context
@@ -1012,7 +734,9 @@ _timeValue (NSString *key)
- (BOOL) isSuperUser
{
return [superUsernames containsObject: login];
[self domainDefaults];
return [[_domainDefaults superUsernames] containsObject: login];
}
/* module access */
+127 -69
View File
@@ -1,93 +1,151 @@
/*
Copyright (C) 2008-2009 Inverse inc.
Copyright (C) 2005 SKYRIX Software AG
/* SOGoUserDefaults.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* 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.
*/
This file is part of SOGo.
#ifndef SOGOUSERDEFAULTS_H
#define SOGOUSERDEFAULTS_H
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.
#import <SOGo/SOGoDefaultsSource.h>
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.
@class NSArray;
@class NSMutableDictionary;
@class NSString;
@class NSTimeZone;
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
extern NSString *SOGoWeekStartJanuary1;
extern NSString *SOGoWeekStartFirst4DayWeek;
extern NSString *SOGoWeekStartFirstFullWeek;
#ifndef __SOGoUserDefaults_H_
#define __SOGoUserDefaults_H_
@interface SOGoUserDefaults : SOGoDefaultsSource
#import <Foundation/NSObject.h>
+ (SOGoUserDefaults *) defaultsForUser: (NSString *) userId
inDomain: (NSString *) domainId;
/*
SOGoUserDefaults
An object with the same API like NSUserDefaults which retrieves profile
information for users in the database.
- (void) setLoginModule: (NSString *) newLoginModule;
- (NSString *) loginModule;
It does NOT store values internally but rather uses an external
mutable dictionary for this (generally coming from SOGoCache)
*/
- (void) setRememberLastModule: (BOOL) rememberLastModule;
- (BOOL) rememberLastModule;
@class NSString, NSURL, NSUserDefaults, NSArray, NSDictionary;
@class NSData, NSCalendarDate, NSMutableDictionary;
- (void) setAppointmentSendEMailReceipts: (BOOL) newPoil;
- (BOOL) appointmentSendEMailReceipts;
@interface SOGoUserDefaults : NSObject
{
NSURL *url;
NSString *uid;
NSString *fieldName;
NSMutableDictionary *values;
- (void) setLongDateFormat: (NSString *) newFormat;
- (void) unsetLongDateFormat;
- (NSString *) longDateFormat;
struct
{
BOOL modified;
BOOL isNew;
BOOL ready;
} defFlags;
}
- (void) setShortDateFormat: (NSString *) newFormat;
- (void) unsetShortDateFormat;
- (NSString *) shortDateFormat;
- (id) initWithTableURL: (NSURL *) theURL
uid: (NSString *) theUID
fieldName: (NSString *) theFieldName;
- (void) setTimeFormat: (NSString *) newFormat;
- (void) unsetTimeFormat;
- (NSString *) timeFormat;
/* value access */
- (void) setValues: (NSDictionary *) theValues;
- (NSDictionary *) values;
- (void) setDayStartTime: (NSString *) newValue;
- (NSString *) dayStartTime;
- (unsigned int) dayStartHour;
- (void) setObject: (id) value
forKey: (NSString *) key;
- (id) objectForKey: (NSString *) key;
- (void) removeObjectForKey: (NSString *) key;
- (void) setDayEndTime: (NSString *) newValue;
- (NSString *) dayEndTime;
- (unsigned int) dayEndHour;
/* typed accessors */
- (void) setTimeZoneName: (NSString *) newValue;
- (NSString *) timeZoneName;
- (NSArray *) arrayForKey: (NSString *)key;
- (NSDictionary *) dictionaryForKey: (NSString *)key;
- (NSData *) dataForKey: (NSString *)key;
- (NSString *) stringForKey: (NSString *)key;
- (BOOL) boolForKey: (NSString *) key;
- (float) floatForKey: (NSString *) key;
- (int) integerForKey: (NSString *) key;
- (void) setTimeZone: (NSTimeZone *) newValue;
- (NSTimeZone *) timeZone;
- (void) setBool: (BOOL) value forKey: (NSString *) key;
- (void) setFloat: (float) value forKey: (NSString *) key;
- (void) setInteger: (int) value forKey: (NSString *) key;
- (void) setTimeFormat: (NSString *) newValue;
- (NSString *) timeFormat;
- (NSString *) jsonRepresentation;
- (void) setLanguage: (NSString *) newValue;
- (NSString *) language;
- (void) fetchProfile;
- (void) setMailShowSubscribedFoldersOnly: (BOOL) newValue;
- (BOOL) mailShowSubscribedFoldersOnly;
/* saving changes */
- (void) setDraftsFolderName: (NSString *) newValue;
- (NSString *) draftsFolderName;
- (BOOL) synchronize;
- (void) setSentFolderName: (NSString *) newValue;
- (NSString *) sentFolderName;
- (void) setTrashFolderName: (NSString *) newValue;
- (NSString *) trashFolderName;
- (void) setFirstDayOfWeek: (int) newValue;
- (int) firstDayOfWeek;
- (void) setFirstWeekOfYear: (NSString *) newValue;
- (NSString *) firstWeekOfYear;
- (void) setMailListViewColumnsOrder: (NSArray *) newValue;
- (NSArray *) mailListViewColumnsOrder;
- (void) setMailMessageCheck: (NSString *) newValue;
- (NSString *) mailMessageCheck;
- (void) setMailComposeMessageType: (NSString *) newValue;
- (NSString *) mailComposeMessageType;
- (void) setMailMessageForwarding: (NSString *) newValue;
- (NSString *) mailMessageForwarding;
- (void) setMailReplyPlacement: (NSString *) newValue;
- (NSString *) mailReplyPlacement;
- (void) setMailSignature: (NSString *) newValue;
- (NSString *) mailSignature;
- (void) setMailSignaturePlacement: (NSString *) newValue;
- (NSString *) mailSignaturePlacement;
- (void) setMailUseOutlookStyleReplies: (BOOL) newValue;
- (BOOL) mailUseOutlookStyleReplies;
- (void) setCalendarCategories: (NSArray *) newValues;
- (NSArray *) calendarCategories;
- (void) setCalendarCategoriesColors: (NSArray *) newValues;
- (NSArray *) calendarCategoriesColors;
- (void) setCalendarShouldDisplayWeekend: (BOOL) newValue;
- (BOOL) calendarShouldDisplayWeekend;
- (void) setReminderEnabled: (BOOL) newValue;
- (BOOL) reminderEnabled;
- (void) setReminderTime: (NSString *) newValue;
- (NSString *) reminderTime;
- (void) setRemindWithASound: (BOOL) newValue;
- (BOOL) remindWithASound;
- (void) setVacationOptions: (NSMutableDictionary *) newValue;
- (NSMutableDictionary *) vacationOptions;
- (void) setForwardOptions: (NSMutableDictionary *) newValue;
- (NSMutableDictionary *) forwardOptions;
@end
#endif /* __SOGoUserDefaults_H__ */
#endif /* SOGOUSERDEFAULTS_H */
File diff suppressed because it is too large Load Diff
+5 -25
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoClassSecurityInfo.h>
@@ -59,23 +58,8 @@
#import "SOGoUserFolder.h"
static NSString *LDAPContactInfoAttribute = nil;
@implementation SOGoUserFolder
+ (void) initialize
{
NSUserDefaults *ud;
if (!LDAPContactInfoAttribute)
{
ud = [NSUserDefaults standardUserDefaults];
LDAPContactInfoAttribute
= [[ud stringForKey: @"SOGoLDAPContactInfoAttribute"] lowercaseString];
[LDAPContactInfoAttribute retain];
}
}
/* hierarchy */
- (NSArray *) toManyRelationshipKeys
@@ -230,8 +214,7 @@ static NSString *LDAPContactInfoAttribute = nil;
results = [NSMutableDictionary dictionary];
contacts
= [[SOGoUserManager sharedUserManager] fetchUsersMatching: uid];
contacts = [[SOGoUserManager sharedUserManager] fetchUsersMatching: uid];
enumerator = [contacts objectEnumerator];
while ((contact = [enumerator nextObject]))
{
@@ -424,13 +407,10 @@ static NSString *LDAPContactInfoAttribute = nil;
field = [currentUser objectForKey: @"c_email"];
[fetch appendFormat: @"<email>%@</email>",
[field stringByEscapingXMLString]];
if (LDAPContactInfoAttribute)
{
field = [currentUser objectForKey: LDAPContactInfoAttribute];
if ([field length])
[fetch appendFormat: @"<info>%@</info>",
[field stringByEscapingXMLString]];
}
field = [currentUser objectForKey: @"info"];
if ([field length])
[fetch appendFormat: @"<info>%@</info>",
[field stringByEscapingXMLString]];
[fetch appendString: @"</user>"];
}
}
+8 -7
View File
@@ -33,6 +33,8 @@
@class LDAPSource;
@protocol SOGoSource;
@interface SOGoUserManager : NSObject
{
@private
@@ -42,17 +44,16 @@
+ (id) sharedUserManager;
+ (BOOL) defaultMailDomainIsConfigured;
- (NSArray *) sourceIDs;
- (NSDictionary *) metadataForSourceID: (NSString *) sourceID;
- (NSArray *) sourceIDsInDomain: (NSString *) domain;
- (NSArray *) authenticationSourceIDs;
- (NSArray *) addressBookSourceIDs;
- (NSArray *) addressBookSourceIDsInDomain: (NSString *) domain;
- (LDAPSource *) sourceWithID: (NSString *) sourceID;
- (NSObject <SOGoSource> *) sourceWithID: (NSString *) sourceID;
- (NSDictionary *) metadataForSourceID: (NSString *) sourceID;
- (NSString *) displayNameForSourceWithID: (NSString *) sourceID;
- (NSDictionary *) contactInfosForUserWithUIDorEmail: (NSString *) uid;
- (NSArray *) fetchContactsMatching: (NSString *) match;
- (NSArray *) fetchContactsMatching: (NSString *) match
inDomain: (NSString *) domain;
- (NSArray *) fetchUsersMatching: (NSString *) filter;
- (NSString *) getCNForUID: (NSString *) uid;
+116 -145
View File
@@ -25,13 +25,14 @@
#import <Foundation/NSLock.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimer.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NSObject+Logs.h>
#import "NSDictionary+BSJSONAdditions.h"
#import "NSArray+Utilities.h"
#import "SOGoDomainDefaults.h"
#import "SOGoSource.h"
#import "SOGoSystemDefaults.h"
#import "SOGoUserManager.h"
#import "SOGoCache.h"
#import "SOGoSource.h"
@@ -39,75 +40,27 @@
#import "LDAPSource.h"
#import "SQLSource.h"
static NSString *defaultMailDomain = nil;
static NSString *LDAPContactInfoAttribute = nil;
static BOOL defaultMailDomainIsConfigured = NO;
static BOOL forceImapLoginWithEmail = NO;
#if defined(THREADSAFE)
static NSLock *lock = nil;
#endif
@implementation SOGoUserManager
+ (void) initialize
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
if (!defaultMailDomain)
{
defaultMailDomain = [ud stringForKey: @"SOGoDefaultMailDomain"];
[defaultMailDomain retain];
defaultMailDomainIsConfigured = YES;
if (!defaultMailDomain)
{
[self warnWithFormat:
@"no domain specified for SOGoDefaultMailDomain,"
@" value set to 'localhost'"];
defaultMailDomain = @"localhost";
}
LDAPContactInfoAttribute = [[ud stringForKey: @"SOGoLDAPContactInfoAttribute"] lowercaseString];
[LDAPContactInfoAttribute retain];
}
if (!forceImapLoginWithEmail)
forceImapLoginWithEmail = [ud boolForKey: @"SOGoForceIMAPLoginWithEmail"];
#if defined(THREADSAFE)
lock = [NSLock new];
#endif
}
+ (BOOL) defaultMailDomainIsConfigured
{
return defaultMailDomainIsConfigured;
}
+ (id) sharedUserManager
{
static id sharedUserManager = nil;
#if defined(THREADSAFE)
[lock lock];
#endif
if (!sharedUserManager)
sharedUserManager = [self new];
#if defined(THREADSAFE)
[lock unlock];
#endif
return sharedUserManager;
}
- (void) _registerSource: (NSDictionary *) udSource
inDomain: (NSString *) domain
{
NSString *sourceID, *value, *type;
NSMutableDictionary *metadata;
id<SOGoSource> ldapSource;
NSObject <SOGoSource> *ldapSource;
BOOL isAddressBook;
Class c;
sourceID = [udSource objectForKey: @"id"];
if ([sourceID length] > 0)
{
@@ -118,13 +71,16 @@ static NSLock *lock = nil;
else
c = [SQLSource class];
ldapSource = [c sourceFromUDSource: udSource];
ldapSource = [c sourceFromUDSource: udSource
inDomain: domain];
if (sourceID)
[_sources setObject: ldapSource forKey: sourceID];
else
[self errorWithFormat: @"id field missing in an user source,"
@" check the SOGoUserSources defaults"];
metadata = [NSMutableDictionary dictionary];
if (domain)
[metadata setObject: domain forKey: @"domain"];
value = [udSource objectForKey: @"canAuthenticate"];
if (value)
[metadata setObject: value forKey: @"canAuthenticate"];
@@ -155,60 +111,51 @@ static NSLock *lock = nil;
@" without id (skipped)"];
}
- (void) _prepareSourcesWithDefaults: (NSUserDefaults *) ud
- (int) _registerSourcesInDomain: (NSString *) domain
{
id o, sources;
NSArray *userSources;
unsigned int count, max;
SOGoDomainDefaults *dd;
if (domain)
dd = [SOGoDomainDefaults defaultsForDomain: domain];
else
dd = [SOGoSystemDefaults sharedSystemDefaults];
userSources = [dd userSources];
max = [userSources count];
for (count = 0; count < max; count++)
[self _registerSource: [userSources objectAtIndex: count]
inDomain: domain];
return max;
}
- (void) _prepareSources
{
NSArray *domains;
unsigned int count, max, total;
_sources = [[NSMutableDictionary alloc] init];
_sourcesMetadata = [[NSMutableDictionary alloc] init];
sources = [NSMutableArray array];
o = [ud arrayForKey: @"SOGoLDAPSources"];
total = [self _registerSourcesInDomain: nil];
domains = [[SOGoSystemDefaults sharedSystemDefaults] domainIds];
max = [domains count];
for (count = 0; count < max; count++)
total += [self _registerSourcesInDomain: [domains objectAtIndex: count]];
if (o)
{
[self errorWithFormat: @"Using depecrated SOGoLDAPSources default. You should now use SOGoUserSources."];
if ([o isKindOfClass: [NSArray class]])
[sources addObjectsFromArray: o];
else
[self errorWithFormat: @"SOGoLDAPSources is NOT an array. Check your defaults. You should now use SOGoUserSources nonetheless."];
}
o = [ud arrayForKey: @"SOGoUserSources"];
if (o)
{
if ([o isKindOfClass: [NSArray class]])
[sources addObjectsFromArray: o];
else
[self errorWithFormat: @"SOGoUserSources is NOT an array. Check your defaults."];
}
if ([sources count])
{
max = [sources count];
for (count = 0; count < max; count++)
[self _registerSource: [sources objectAtIndex: count]];
}
else
{
[self errorWithFormat: @"No authentication sources defined - nobody will be able to login. Check your defaults."];
}
if (!total)
[self errorWithFormat: @"No authentication sources defined - nobody will be able to login. Check your defaults."];
}
- (id) init
{
NSUserDefaults *ud;
if ((self = [super init]))
{
ud = [NSUserDefaults standardUserDefaults];
_sources = nil;
_sourcesMetadata = nil;
[self _prepareSourcesWithDefaults: ud];
[self _prepareSources];
}
return self;
@@ -221,31 +168,60 @@ static NSLock *lock = nil;
[super dealloc];
}
- (NSArray *) sourceIDs
- (NSArray *) sourceIDsInDomain: (NSString *) domain
{
return [_sources allKeys];
NSMutableArray *sourceIDs;
NSArray *keys;
int count, max;
NSString *currentID, *sourceDomain;
NSObject <SOGoSource> *currentSource;
keys = [_sources allKeys];
max = [keys count];
sourceIDs = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
currentID = [keys objectAtIndex: count];
currentSource = [_sources objectForKey: currentID];
sourceDomain = [currentSource domain];
if (!domain || [sourceDomain isEqualToString: domain])
[sourceIDs addObject: currentID];
}
return sourceIDs;
}
- (NSArray *) _sourcesOfType: (NSString *) sourceType
inDomain: (NSString *) domain
{
NSMutableArray *sourceIDs;
NSEnumerator *allIDs;
NSString *currentID;
NSNumber *canAuthenticate;
NSNumber *typeValue;
NSDictionary *metadata;
sourceIDs = [NSMutableArray array];
allIDs = [[_sources allKeys] objectEnumerator];
while ((currentID = [allIDs nextObject]))
while ((currentID = [allIDs nextObject]))
{
canAuthenticate = [[_sourcesMetadata objectForKey: currentID]
objectForKey: sourceType];
if ([canAuthenticate boolValue])
[sourceIDs addObject: currentID];
metadata = [_sourcesMetadata objectForKey: currentID];
if (!domain
|| [[metadata objectForKey: @"domain"] isEqualToString: domain])
{
typeValue = [metadata objectForKey: sourceType];
if ([typeValue boolValue])
[sourceIDs addObject: currentID];
}
}
return sourceIDs;
}
- (NSObject <SOGoSource> *) sourceWithID: (NSString *) sourceID
{
return [_sources objectForKey: sourceID];
}
- (NSDictionary *) metadataForSourceID: (NSString *) sourceID
{
return [_sourcesMetadata objectForKey: sourceID];
@@ -253,17 +229,12 @@ static NSLock *lock = nil;
- (NSArray *) authenticationSourceIDs
{
return [self _sourcesOfType: @"canAuthenticate"];
return [self _sourcesOfType: @"canAuthenticate" inDomain: nil];
}
- (NSArray *) addressBookSourceIDs
- (NSArray *) addressBookSourceIDsInDomain: (NSString *) domain
{
return [self _sourcesOfType: @"isAddressBook"];
}
- (LDAPSource *) sourceWithID: (NSString *) sourceID
{
return [_sources objectForKey: sourceID];
return [self _sourcesOfType: @"isAddressBook" inDomain: domain];
}
- (NSString *) displayNameForSourceWithID: (NSString *) sourceID
@@ -308,7 +279,18 @@ static NSLock *lock = nil;
- (NSString *) getImapLoginForUID: (NSString *) uid
{
return ((forceImapLoginWithEmail) ? [self getEmailForUID: uid] : uid);
NSDictionary *contactInfos;
NSString *domain;
SOGoDomainDefaults *dd;
contactInfos = [self contactInfosForUserWithUIDorEmail: uid];
domain = [contactInfos objectForKey: @"c_domain"];
if ([domain length])
dd = [SOGoDomainDefaults defaultsForDomain: domain];
else
dd = [SOGoSystemDefaults sharedSystemDefaults];
return ([dd forceIMAPLoginWithEmail] ? [self getEmailForUID: uid] : uid);
}
- (NSString *) getUIDForEmail: (NSString *) email
@@ -324,7 +306,7 @@ static NSLock *lock = nil;
- (BOOL) _sourceCheckLogin: (NSString *) login
andPassword: (NSString *) password
{
id<SOGoSource> ldapSource;
NSObject <SOGoSource> *ldapSource;
NSEnumerator *authIDs;
NSString *currentID;
BOOL checkOK;
@@ -348,10 +330,6 @@ static NSLock *lock = nil;
NSString *dictPassword, *jsonUser;
BOOL checkOK;
#if defined(THREADSAFE)
[lock lock];
#endif
jsonUser = [[SOGoCache sharedCache] userAttributesForLogin: login];
currentUser = [NSMutableDictionary dictionaryWithJSONString: jsonUser];
dictPassword = [currentUser objectForKey: @"password"];
@@ -378,23 +356,25 @@ static NSLock *lock = nil;
else
checkOK = NO;
#if defined(THREADSAFE)
[lock unlock];
#endif
return checkOK;
}
- (void) _fillContactMailRecords: (NSMutableDictionary *) contact
{
NSString *uid, *systemEmail;
NSString *uid, *domain, *systemEmail;
NSMutableArray *emails;
SOGoDomainDefaults *dd;
domain = [contact objectForKey: @"c_domain"];
if ([domain length])
dd = [SOGoDomainDefaults defaultsForDomain: domain];
else
dd = [SOGoSystemDefaults sharedSystemDefaults];
emails = [contact objectForKey: @"emails"];
uid = [contact objectForKey: @"c_uid"];
if ([uid rangeOfString: @"@"].location == NSNotFound)
systemEmail
= [NSString stringWithFormat: @"%@@%@", uid, defaultMailDomain];
= [NSString stringWithFormat: @"%@@%@", uid, [dd mailDomain]];
else
systemEmail = uid;
[emails addObject: systemEmail];
@@ -422,7 +402,8 @@ static NSLock *lock = nil;
[currentUser setObject: [NSNumber numberWithBool: YES]
forKey: @"MailAccess"];
ldapSources = [[self authenticationSourceIDs] objectEnumerator];
ldapSources = [[self authenticationSourceIDs]
objectEnumerator];
while ((sourceID = [ldapSources nextObject]))
{
currentSource = [_sources objectForKey: sourceID];
@@ -500,15 +481,13 @@ static NSLock *lock = nil;
contactInfos = [NSMutableDictionary dictionary];
jsonUser = [[SOGoCache sharedCache] userAttributesForLogin: aUID];
currentUser = [NSMutableDictionary dictionaryWithJSONString: jsonUser];
#if defined(THREADSAFE)
[lock lock];
#endif
if (!([currentUser objectForKey: @"emails"]
&& [currentUser objectForKey: @"cn"]))
{
// We make sure that we either have no occurence of a cache entry or that
// we have an occurence with only a cached password. In the latter case, we
// update the entry with the remaining information and recache the value.
// We make sure that we either have no occurence of a cache entry or
// that we have an occurence with only a cached password. In the
// latter case, we update the entry with the remaining information
// and recache the value.
if (!currentUser || ([currentUser count] == 1 && [currentUser objectForKey: @"password"]))
{
newUser = YES;
@@ -528,10 +507,6 @@ static NSLock *lock = nil;
currentUser = nil;
}
}
#if defined(THREADSAFE)
[lock unlock];
#endif
}
else
currentUser = nil;
@@ -545,7 +520,7 @@ static NSLock *lock = nil;
NSDictionary *userEntry;
NSArray *newContacts;
NSMutableArray *emails;
NSString *uid, *email, *infoAttribute;
NSString *uid, *email, *info;
compactContacts = [NSMutableDictionary dictionary];
while ((userEntry = [contacts nextObject]))
@@ -581,16 +556,10 @@ static NSLock *lock = nil;
email = [userEntry objectForKey: @"xmozillasecondemail"];
if (email && ![emails containsObject: email])
[emails addObject: email];
if ([LDAPContactInfoAttribute length]
&& ![[returnContact
objectForKey: LDAPContactInfoAttribute] length])
{
infoAttribute
= [userEntry objectForKey: LDAPContactInfoAttribute];
if ([infoAttribute length])
[returnContact setObject: infoAttribute
forKey: LDAPContactInfoAttribute];
}
info = [userEntry objectForKey: @"c_info"];
if ([info length] > 0
&& ![[returnContact objectForKey: @"c_info"] length])
[returnContact setObject: info forKey: @"c_info"];
[self _fillContactMailRecords: returnContact];
}
}
@@ -621,15 +590,17 @@ static NSLock *lock = nil;
}
- (NSArray *) fetchContactsMatching: (NSString *) filter
inDomain: (NSString *) domain
{
return [self _fetchEntriesInSources: [self addressBookSourceIDs]
matching: filter];
return [self
_fetchEntriesInSources: [self addressBookSourceIDsInDomain: domain]
matching: filter];
}
- (NSArray *) fetchUsersMatching: (NSString *) filter
{
return [self _fetchEntriesInSources: [self authenticationSourceIDs]
matching: filter];
matching: filter];
}
- (NSString *) getLoginForDN: (NSString *) theDN
+88
View File
@@ -0,0 +1,88 @@
/*
Copyright (C) 2008-2009 Inverse inc.
Copyright (C) 2005 SKYRIX Software AG
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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#ifndef __SOGoUserDefaults_H_
#define __SOGoUserDefaults_H_
#import <Foundation/NSObject.h>
/*
SOGoUserDefaults
An object with the same API like NSUserDefaults which retrieves profile
information for users in the database.
It does NOT store values internally but rather uses an external
mutable dictionary for this (generally coming from SOGoCache)
*/
@class NSString, NSUserDefaults, NSArray, NSDictionary;
@class NSData, NSCalendarDate, NSMutableDictionary;
typedef enum _SOGoUserProfileType {
SOGoUserProfileTypeDefaults, /* configurable user preferences */
SOGoUserProfileTypeSettings /* user environment state */
} SOGoUserProfileType;
@interface SOGoUserProfile : NSObject
{
NSString *uid;
NSMutableDictionary *values;
SOGoUserProfileType profileType;
struct
{
BOOL modified;
BOOL isNew;
BOOL ready;
} defFlags;
}
+ (id) userProfileWithType: (SOGoUserProfileType) newProfileType
forUID: (NSString *) theUID;
- (void) setProfileType: (SOGoUserProfileType) newProfileType;
- (NSString *) profileTypeName;
- (void) setUID: (NSString *) newUID;
- (NSString *) uid;
/* value access */
- (void) setValues: (NSDictionary *) theValues;
- (NSDictionary *) values;
- (void) setObject: (id) value
forKey: (NSString *) key;
- (id) objectForKey: (NSString *) key;
- (void) removeObjectForKey: (NSString *) key;
- (NSString *) jsonRepresentation;
- (void) fetchProfile;
/* saving changes */
- (BOOL) synchronize;
@end
#endif /* __SOGoUserDefaults_H__ */
+373
View File
@@ -0,0 +1,373 @@
/*
Copyright (C) 2008-2009 Inverse inc.
Copyright (C) 2005 SKYRIX Software AG
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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import "NSObject+Utilities.h"
#import "NSString+Utilities.h"
#import "NSDictionary+BSJSONAdditions.h"
#import "SOGoCache.h"
#import "SOGoUserProfile.h"
@implementation SOGoUserProfile
+ (id) userProfileWithType: (SOGoUserProfileType) newProfileType
forUID: (NSString *) newUID
{
id userProfile;
userProfile = [self new];
[userProfile autorelease];
[userProfile setProfileType: newProfileType];
[userProfile setUID: newUID];
return userProfile;
}
- (id) init
{
if ((self = [super init]))
{
uid = nil;
values = nil;
defFlags.ready = NO;
defFlags.isNew = NO;
}
return self;
}
- (void) dealloc
{
[values release];
[uid release];
[super dealloc];
}
/* accessors */
- (void) setProfileType: (SOGoUserProfileType) newProfileType
{
profileType = newProfileType;
}
- (NSString *) profileTypeName
{
NSString *profileTypeName;
switch (profileType)
{
case SOGoUserProfileTypeDefaults:
profileTypeName = @"defaults profile";
break;
case SOGoUserProfileTypeSettings:
profileTypeName = @"settings profile";
break;
default:
profileTypeName = @"<unknown profile type>";
}
return profileTypeName;
}
- (void) setUID: (NSString *) newUID
{
ASSIGN (uid, newUID);
}
- (NSString *) uid
{
return uid;
}
/* subclass methods */
- (BOOL) storeJSONProfileInDB: (NSString *) jsonRepresentation
{
[self subclassResponsibility: _cmd];
return NO;
}
- (NSString *) fetchJSONProfileFromDB
{
[self subclassResponsibility: _cmd];
return nil;
}
/* operation */
- (NSString *) _convertPListToJSON: (NSString *) plistValue
{
NSData *plistData;
NSDictionary *plist;
NSString *jsonValue, *error;
plistData = [plistValue dataUsingEncoding: NSUTF8StringEncoding];
plist = [NSPropertyListSerialization propertyListFromData: plistData
mutabilityOption: NSPropertyListMutableContainers
format: NULL
errorDescription: &error];
if (plist)
{
[self logWithFormat: @"database value for %@"
@" (uid: '%@') is a plist", [self profileTypeName], uid];
jsonValue = [plist jsonStringValue];
}
else
{
[self errorWithFormat: @"failed to parse property list value for %@"
@" (error: %@): %@", [self profileTypeName], error, plistValue];
jsonValue = nil;
}
if (!jsonValue)
jsonValue = @"{}";
return jsonValue;
}
- (NSString *) jsonRepresentation
{
SOGoCache *cache;
NSString *jsonValue;
cache = [SOGoCache sharedCache];
if (profileType == SOGoUserProfileTypeDefaults)
jsonValue = [cache userDefaultsForLogin: uid];
else
jsonValue = [cache userSettingsForLogin: uid];
if ([jsonValue length])
{
defFlags.ready = YES;
defFlags.isNew = NO;
}
else
{
jsonValue = [self fetchJSONProfileFromDB];
if ([jsonValue length])
{
if (![jsonValue isJSONString])
jsonValue = [self _convertPListToJSON: jsonValue];
if (profileType == SOGoUserProfileTypeDefaults)
[cache setUserDefaults: jsonValue forLogin: uid];
else
[cache setUserSettings: jsonValue forLogin: uid];
}
else
jsonValue = @"{}";
}
return jsonValue;
}
- (void) primaryFetchProfile
{
NSString *jsonValue;
defFlags.modified = NO;
[values release];
jsonValue = [self jsonRepresentation];
values = [NSMutableDictionary dictionaryWithJSONString: jsonValue];
if (values)
[values retain];
else
[self errorWithFormat: @"failure parsing json string: '%@'", jsonValue];
}
- (BOOL) _isReadyOrRetry
{
BOOL rc;
if (defFlags.ready)
rc = YES;
else
{
[self primaryFetchProfile];
rc = defFlags.ready;
}
return rc;
}
- (NSString *) _sqlJsonRepresentation: (NSString *) jsonRepresentation
{
NSMutableString *sql;
sql = [jsonRepresentation mutableCopy];
[sql autorelease];
[sql replaceString: @"\\" withString: @"\\\\"];
[sql replaceString: @"'" withString: @"''"];
return sql;
}
- (BOOL) primaryStoreProfile
{
NSString *jsonRepresentation;
SOGoCache *cache;
BOOL rc;
jsonRepresentation = [values jsonStringValue];
if (jsonRepresentation)
{
rc = [self storeJSONProfileInDB: jsonRepresentation];
if (rc)
{
cache = [SOGoCache sharedCache];
if (profileType == SOGoUserProfileTypeDefaults)
[cache setUserDefaults: jsonRepresentation
forLogin: uid];
else
[cache setUserSettings: jsonRepresentation
forLogin: uid];
}
}
else
{
[self errorWithFormat: @"Unable to convert (%@) to a JSON string for"
@" type: %@ and login: %@", values, [self profileTypeName], uid];
rc = NO;
}
return rc;
}
- (void) fetchProfile
{
if (!values)
[self primaryFetchProfile];
}
/* value access */
- (void) setValues: (NSDictionary *) theValues
{
if ([self _isReadyOrRetry])
{
[values release];
values = [[NSMutableDictionary alloc] init];
[values addEntriesFromDictionary: theValues];
defFlags.modified = YES;
}
}
- (NSDictionary *) values
{
NSDictionary *returnValues;
if ([self _isReadyOrRetry])
returnValues = values;
else
returnValues = nil;
return returnValues;
}
- (void) setObject: (id) value
forKey: (NSString *) key
{
id old;
if ([self _isReadyOrRetry])
{
/* check whether the value is actually modified */
if (!defFlags.modified)
{
old = [values objectForKey: key];
if (old == value || [old isEqual: value]) /* value didn't change */
return;
#warning Note that this work-around only works for first-level objects.
/* we need to this because our typed accessors convert to strings */
// TODO: especially problematic with bools
if ([value isKindOfClass: [NSString class]]) {
if (![old isKindOfClass: [NSString class]])
if ([[old description] isEqualToString: value])
return;
}
}
/* set in hash and mark as modified */
if (value)
[values setObject: value forKey: key];
else
[values removeObjectForKey: key];
defFlags.modified = YES;
}
}
- (void) removeObjectForKey: (NSString *) key
{
[self setObject: nil forKey: key];
}
- (id) objectForKey: (NSString *) key
{
return [[self values] objectForKey: key];
}
/* saving changes */
- (BOOL) synchronize
{
BOOL rc;
// if (!defFlags.modified) /* was not modified */
// return YES;
rc = NO;
/* ensure fetched data (more or less guaranteed by modified!=0) */
[self fetchProfile];
if (values)
{
/* store */
if ([self primaryStoreProfile])
{
rc = YES;
// /* refetch */
// [self primaryFetchProfile];
}
else
{
[self primaryFetchProfile];
return NO;
}
}
return rc;
}
- (NSString *) description
{
return [values description];
}
@end
-1
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/SoDefaultRenderer.h>
#import <NGObjWeb/WOApplication.h>
+2
View File
@@ -35,6 +35,8 @@
@interface SQLSource : NSObject <SOGoSource>
{
NSString *_sourceID;
NSString *_domain;
NSString *_domainAttribute;
NSArray *_mailFields;
NSString *_userPasswordAlgorithm;
NSURL *_viewURL;
+35 -2
View File
@@ -68,8 +68,10 @@
@implementation SQLSource
+ (id) sourceFromUDSource: (NSDictionary *) udSource
inDomain: (NSString *) domain
{
return [[[self alloc] initFromUDSource: udSource] autorelease];
return [[[self alloc] initFromUDSource: udSource
inDomain: domain] autorelease];
}
- (id) init
@@ -96,7 +98,10 @@
}
- (id) initFromUDSource: (NSDictionary *) udSource
inDomain: (NSString *) sourceDomain
{
NSString *udDomainAttribute;
self = [self init];
ASSIGN(_sourceID, [udSource objectForKey: @"id"]);
@@ -108,7 +113,30 @@
if ([udSource objectForKey: @"viewURL"])
_viewURL = [[NSURL alloc] initWithString: [udSource objectForKey: @"viewURL"]];
#warning this domain code has no effect yet
/* FIXME: the queries below do not setup c_domain. */
udDomainAttribute = [udSource objectForKey: @"domainAttribute"];
if ([sourceDomain length])
{
if ([udDomainAttribute length])
{
[self errorWithFormat: @"cannot define 'domainAttribute'"
@" for a domain-based source (%@)", _sourceID];
[self autorelease];
return nil;
}
else
{
ASSIGN (_domain, sourceDomain);
}
}
else
{
if ([udDomainAttribute length])
ASSIGN (_domainAttribute, udDomainAttribute);
}
if (!_viewURL)
{
[self autorelease];
@@ -118,6 +146,11 @@
return self;
}
- (NSString *) domain
{
return _domain;
}
- (BOOL) _isPassword: (NSString *) plainPassword
equalTo: (NSString *) encryptedPassword
{
+2 -2
View File
@@ -23,11 +23,11 @@
#ifndef WOCONTEXT_SOGo_H
#define WOCONTEXT_SOGo_H
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
@interface WOContext (SOGoSOPEUtilities)
- (NSArray *)resourceLookupLanguages;
- (NSArray *) resourceLookupLanguages;
@end
+25 -8
View File
@@ -27,7 +27,8 @@
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOSession.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGoUser.h>
#import <SOGoUserDefaults.h>
#import "WOContext+SOGo.h"
@@ -36,16 +37,32 @@
- (NSArray *) resourceLookupLanguages
{
NSMutableArray *languages;
NSArray *browserLanguages;
SOGoUser *user;
NSString *language;
languages = [NSMutableArray array];
if (activeUser && [activeUser language])
[languages addObject: [activeUser language]];
if ([self hasSession])
[languages addObjectsFromArray: [[self session] languages]];
user = [self activeUser];
if ([user isKindOfClass: [SOGoUser class]])
{
language = [[user userDefaults] language];
[languages addObject: language];
language = [[user domainDefaults] language];
[languages addObject: language];
}
else
[languages addObjectsFromArray: [[self request] browserLanguages]];
{
browserLanguages = [[self request] browserLanguages];
[languages addObjectsFromArray: browserLanguages];
}
// if (activeUser && [activeUser language])
// [languages addObject: [activeUser language]];
// if ([self hasSession])
// [languages addObjectsFromArray: [[self session] languages]];
// else
// [languages addObjectsFromArray: [[self request] browserLanguages]];
return languages;
}
@@ -29,6 +29,8 @@
#import "iCalEntityObject+Utilities.h"
#warning we should move this into Appointments.
@implementation iCalEntityObject (SOGoAddition)
- (iCalPerson *) findParticipant: (SOGoUser *) user
+2 -2
View File
@@ -37,7 +37,7 @@
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserProfile.h>
#import "SOGoToolBackup.h"
@@ -301,7 +301,7 @@
{
NSEnumerator *ldapSources;
NSString *sourceID;
LDAPSource *currentSource;
NSObject <SOGoSource> *currentSource;
SOGoUserManager *lm;
NSDictionary *userEntry;
BOOL done;
+8 -8
View File
@@ -36,7 +36,7 @@
#import <SOGo/SOGoUserManager.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserProfile.h>
#import "SOGoToolRestore.h"
@@ -527,7 +527,7 @@
- (BOOL) restoreUserPreferencesFromUserRecord: (NSDictionary *) userRecord
{
SOGoUser *sogoUser;
NSUserDefaults *storedPreferences;
SOGoUserProfile *up;
NSArray *preferences;
BOOL rc;
@@ -537,13 +537,13 @@
rc = YES;
sogoUser = [SOGoUser userWithLogin: userID roles: nil];
storedPreferences = [sogoUser userDefaults];
[storedPreferences setValues: [preferences objectAtIndex: 0]];
[storedPreferences synchronize];
up = [[sogoUser userDefaults] source];
[up setValues: [preferences objectAtIndex: 0]];
[up synchronize];
storedPreferences = [sogoUser userSettings];
[storedPreferences setValues: [preferences objectAtIndex: 1]];
[storedPreferences synchronize];
up = [[sogoUser userSettings] source];
[up setValues: [preferences objectAtIndex: 1]];
[up synchronize];
}
else
{
+2 -2
View File
@@ -26,18 +26,18 @@
#import <NGObjWeb/WODirectAction.h>
@class NSString;
@class NSUserDefaults;
@class NSMutableString;
@class NSMutableDictionary;
@class LDAPUserManager;
@class SOGoGCSFolder;
@class SOGoUserSettings;
@interface UIxFolderActions : WODirectAction
{
SOGoGCSFolder *clientObject;
LDAPUserManager *um;
NSUserDefaults *ud;
SOGoUserSettings *us;
NSString *owner;
NSString *login;
NSString *baseFolder;
+5 -5
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
@@ -42,6 +41,7 @@
#import <SoObjects/SOGo/SOGoParentFolder.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserSettings.h>
#import "WODirectAction+SOGo.h"
@@ -62,11 +62,11 @@
baseFolder = [[clientObject container] nameInContainer];
um = [SOGoUserManager sharedUserManager];
ud = [activeUser userSettings];
moduleSettings = [ud objectForKey: baseFolder];
us = [activeUser userSettings];
moduleSettings = [us objectForKey: baseFolder];
if (!moduleSettings)
moduleSettings = [NSMutableDictionary dictionary];
[ud setObject: moduleSettings forKey: baseFolder];
[us setObject: moduleSettings forKey: baseFolder];
mailInvitationParam
= [[context request] formValueForKey: @"mail-invitation"];
@@ -174,7 +174,7 @@
else
[folderSubscription addObjectUniquely: folderName];
[ud synchronize];
[us synchronize];
return [self responseWith204];
}
-1
View File
@@ -22,7 +22,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WORequest.h>
+27 -32
View File
@@ -1,3 +1,4 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
@@ -21,30 +22,21 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOResourceManager.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUserProfile.h>
#import <SOGo/SOGoUserSettings.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoWebAuthenticator.h>
#import "UIxPageFrame.h"
static NSString *siteFavicon = nil;
@implementation UIxPageFrame
+ (void) initialize
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
siteFavicon = [ud stringForKey: @"SOGoFaviconRelativeURL"];
[siteFavicon retain];
}
- (id) init
{
if ((self = [super init]))
@@ -184,7 +176,14 @@ static NSString *siteFavicon = nil;
- (NSString *) siteFavicon
{
return (!siteFavicon ? [self urlForResourceFilename: @"sogo.ico"] : siteFavicon);
NSString *siteFavicon;
siteFavicon = [[SOGoSystemDefaults sharedSystemDefaults]
faviconRelativeURL];
return (siteFavicon
? siteFavicon
: [self urlForResourceFilename: @"sogo.ico"]);
}
/* page based JavaScript */
@@ -192,13 +191,13 @@ static NSString *siteFavicon = nil;
- (NSString *) _stringsForFramework: (NSString *) framework
{
NSString *language, *frameworkName;
SOGoUserDefaults *ud;
id table;
frameworkName = [NSString stringWithFormat: @"%@.SOGo",
(framework ? framework : [self frameworkName])];
language = [[context activeUser] language];
if (!language)
language = [SOGoUser language];
ud = [[context activeUser] userDefaults];
language = [ud language];
table
= [[self resourceManager] stringTableWithName: @"Localizable"
@@ -438,24 +437,21 @@ static NSString *siteFavicon = nil;
- (NSString *) userLanguage
{
NSString *language;
SOGoUserDefaults *ud;
language = [[context activeUser] language];
if (!language)
language = [SOGoUser language];
ud = [[context activeUser] userDefaults];
return language;
return [ud language];
}
- (NSString *) userSettings
{
SOGoUserDefaults *userSettings;
SOGoUserSettings *us;
NSString *jsonResult;
userSettings = (SOGoUserDefaults *)[[context activeUser] userSettings];
if (userSettings)
jsonResult = [userSettings jsonRepresentation];
else
us = [[context activeUser] userSettings];
jsonResult = [[us source] jsonRepresentation];
if (!jsonResult)
jsonResult = @"{}";
return jsonResult;
@@ -463,13 +459,12 @@ static NSString *siteFavicon = nil;
- (NSString *) userDefaults
{
SOGoUserDefaults *userDefaults;
SOGoUserDefaults *ud;
NSString *jsonResult;
userDefaults = (SOGoUserDefaults *)[[context activeUser] userDefaults];
if (userDefaults)
jsonResult = [userDefaults jsonRepresentation];
else
ud = [[context activeUser] userDefaults];
jsonResult = [[ud source] jsonRepresentation];
if (!jsonResult)
jsonResult = @"{}";
return jsonResult;
+18 -26
View File
@@ -24,28 +24,19 @@
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOResponse.h>
#import <NGObjWeb/WORequest.h>
#import <SoObjects/SOGo/SOGoUserManager.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoObject.h>
#import <SoObjects/SOGo/SOGoGroup.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoGroup.h>
#import <SOGo/SOGoObject.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserManager.h>
#import <UI/SOGoUI/SOGoACLAdvisory.h>
#import <Foundation/NSUserDefaults.h>
#import "UIxUserRightsEditor.h"
static BOOL sendACLAdvisories = NO;
@implementation UIxUserRightsEditor
+ (void) initialize
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"];
}
- (id) init
{
if ((self = [super init]))
@@ -93,7 +84,7 @@ static BOOL sendACLAdvisories = NO;
- (BOOL) _initRights
{
BOOL response;
NSString *newUID;
NSString *newUID, *domain;
SOGoUserManager *um;
SOGoObject *clientObject;
SOGoGroup *group;
@@ -112,7 +103,8 @@ static BOOL sendACLAdvisories = NO;
{
if (![newUID hasPrefix: @"@"])
{
group = [SOGoGroup groupWithIdentifier: newUID];
domain = [[context activeUser] domain];
group = [SOGoGroup groupWithIdentifier: newUID inDomain: domain];
if (group)
newUID = [NSString stringWithFormat: @"@%@", newUID];
}
@@ -147,12 +139,12 @@ static BOOL sendACLAdvisories = NO;
- (void) sendACLAdvisoryTemplateForObject: (id) theObject
{
NSString *language, *pageName;
SOGoUser *user;
SOGoUserDefaults *ud;
SOGoACLAdvisory *page;
WOApplication *app;
user = [SOGoUser userWithLogin: uid roles: nil];
language = [user language];
ud = [[SOGoUser userWithLogin: uid roles: nil] userDefaults];
language = [ud language];
pageName = [NSString stringWithFormat: @"SOGoACL%@ModificationAdvisory",
language];
@@ -166,6 +158,7 @@ static BOOL sendACLAdvisories = NO;
- (id <WOActionResults>) saveUserRightsAction
{
id <WOActionResults> response;
SOGoDomainDefaults *dd;
if (![self _initRights])
response = [NSException exceptionWithHTTPStatus: 403
@@ -179,11 +172,10 @@ static BOOL sendACLAdvisories = NO;
[self updateRights];
[[self clientObject] setRoles: userRights forUser: uid];
if (![o isEqualToArray: userRights] && sendACLAdvisories)
{
[self sendACLAdvisoryTemplateForObject: [self clientObject]];
}
dd = [[context activeUser] domainDefaults];
if (![o isEqualToArray: userRights] && [dd aclSendEMailNotifications])
[self sendACLAdvisoryTemplateForObject: [self clientObject]];
response = [self jsCloseWithRefreshMethod: nil];
}
+4 -1
View File
@@ -28,6 +28,7 @@
#import <SoObjects/SOGo/NSObject+Utilities.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserDefaults.h>
#import "WODirectAction+SOGo.h"
@@ -88,12 +89,14 @@
NSArray *paths;
NSBundle *bundle;
NSDictionary *strings;
SOGoUserDefaults *ud;
bundle = [NSBundle bundleForClass: [self class]];
if (!bundle)
bundle = [NSBundle mainBundle];
userLanguage = [[context activeUser] language];
ud = [[context activeUser] userDefaults];
userLanguage = [ud language];
paths = [bundle pathsForResourcesOfType: @"strings"
inDirectory: [NSString stringWithFormat: @"%@.lproj",
userLanguage]
+1 -1
View File
@@ -28,7 +28,7 @@
@interface UIxContactFoldersView : UIxComponent
{
NSUserDefaults *ud;
SOGoUserSettings *us;
NSString *selectorComponentClass;
NSMutableDictionary *moduleSettings;
id currentFolder;
+40 -41
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoObject.h>
@@ -38,16 +37,17 @@
#import <GDLContentStore/GCSFolder.h>
#import <GDLContentStore/GCSFolderManager.h>
#import <SoObjects/SOGo/SOGoUserManager.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/Contacts/SOGoContactFolders.h>
#import <SoObjects/Contacts/SOGoContactFolder.h>
#import <SoObjects/Contacts/SOGoContactGCSFolder.h>
#import <SoObjects/Contacts/SOGoContactSourceFolder.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <Contacts/SOGoContactFolders.h>
#import <Contacts/SOGoContactFolder.h>
#import <Contacts/SOGoContactGCSFolder.h>
#import <Contacts/SOGoContactSourceFolder.h>
#import "UIxContactFoldersView.h"
@@ -64,11 +64,11 @@
module = [clientObject nameInContainer];
ud = [activeUser userSettings];
moduleSettings = [ud objectForKey: module];
us = [activeUser userSettings];
moduleSettings = [us objectForKey: module];
if (!moduleSettings)
moduleSettings = [NSMutableDictionary dictionary];
[ud setObject: moduleSettings forKey: module];
[us setObject: moduleSettings forKey: module];
}
- (id <WOActionResults>) mailerContactsAction
@@ -139,18 +139,14 @@
- (NSArray *) _responseForResults: (NSArray *) results
{
NSEnumerator *contacts;
NSString *email, *infoKey, *info;
NSString *email, *info;
NSDictionary *contact;
NSMutableArray *formattedContacts;
NSMutableDictionary *formattedContact;
NSUserDefaults *sud;
formattedContacts = [NSMutableArray arrayWithCapacity: [results count]];
if ([results count] > 0)
{
sud = [NSUserDefaults standardUserDefaults];
infoKey = [[sud stringForKey: @"SOGoLDAPContactInfoAttribute"] lowercaseString];
contacts = [results objectEnumerator];
contact = [contacts nextObject];
while (contact)
@@ -165,13 +161,10 @@
forKey: @"name"];
[formattedContact setObject: email
forKey: @"email"];
if ([infoKey length] > 0)
{
info = [contact objectForKey: infoKey];
if (info != nil)
[formattedContact setObject: info
forKey: @"contactInfo"];
}
info = [contact objectForKey: @"c_info"];
if (info != nil)
[formattedContact setObject: info
forKey: @"contactInfo"];
[formattedContacts addObject: formattedContact];
}
contact = [contacts nextObject];
@@ -276,7 +269,7 @@
{
NSDictionary *data;
NSArray *contacts;
NSString *searchText;
NSString *searchText, *domain;
id <WOActionResults> result;
SOGoUserManager *um;
@@ -284,11 +277,14 @@
if ([searchText length] > 0)
{
um = [SOGoUserManager sharedUserManager];
domain = [[context activeUser] domain];
contacts
= [self _responseForResults: [um fetchContactsMatching: searchText]];
data = [NSDictionary dictionaryWithObjectsAndKeys: searchText, @"searchText",
contacts, @"contacts",
nil];
= [self _responseForResults: [um fetchContactsMatching: searchText
inDomain: domain]];
data = [NSDictionary dictionaryWithObjectsAndKeys:
searchText, @"searchText",
contacts, @"contacts",
nil];
result = [self responseWithStatus: 200];
[(WOResponse*)result appendContentString: [data jsonRepresentation]];
}
@@ -367,18 +363,15 @@
- (void) checkDefaultModulePreference
{
NSUserDefaults *clientUD;
NSString *pref;
SOGoUserDefaults *ud;
if (![self isPopup])
{
clientUD = [[context activeUser] userDefaults];
pref = [clientUD stringForKey: @"SOGoUIxDefaultModule"];
if (pref && [pref isEqualToString: @"Last"])
ud = [[context activeUser] userDefaults];
if ([ud rememberLastModule])
{
[clientUD setObject: @"Contacts" forKey: @"SOGoUIxLastModule"];
[clientUD synchronize];
[ud setLoginModule: @"Contacts"];
[ud synchronize];
}
}
}
@@ -392,7 +385,6 @@
{
SOGoContactFolders *folderContainer;
[self checkDefaultModulePreference];
folderContainer = [self clientObject];
return [folderContainer subFolders];
@@ -436,9 +428,16 @@
else
return [self responseWithStatus: 400];
[ud synchronize];
[us synchronize];
return [self responseWithStatus: 204];
}
- (id) defaultAction
{
[self checkDefaultModulePreference];
return [super defaultAction];
}
@end
+15 -14
View File
@@ -37,14 +37,15 @@
#import <NGCards/iCalPerson.h>
#import <NGCards/iCalDateTime.h>
#import <SoObjects/SOGo/SOGoDateFormatter.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
#import <SoObjects/Appointments/iCalEntityObject+SOGo.h>
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/Mailer/SOGoMailBodyPart.h>
#import <SOGo/SOGoDateFormatter.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/iCalEntityObject+Utilities.h>
#import <Appointments/iCalEntityObject+SOGo.h>
#import <Appointments/SOGoAppointmentFolder.h>
#import <Appointments/SOGoAppointmentObject.h>
#import <Mailer/SOGoMailObject.h>
#import <Mailer/SOGoMailBodyPart.h>
#import "UIxMailPartICalViewer.h"
@@ -167,11 +168,11 @@
- (NSCalendarDate *) startCalendarDate
{
NSCalendarDate *date;
NSTimeZone *timeZone;
SOGoUserDefaults *ud;
date = [[self inEvent] startDate];
timeZone = [[context activeUser] timeZone];
[date setTimeZone: timeZone];
ud = [[context activeUser] userDefaults];
[date setTimeZone: [ud timeZone]];
return date;
}
@@ -189,11 +190,11 @@
- (NSCalendarDate *) endCalendarDate
{
NSCalendarDate *date;
NSTimeZone *timeZone;
SOGoUserDefaults *ud;
date = [[self inEvent] endDate];
timeZone = [[context activeUser] timeZone];
[date setTimeZone: timeZone];
ud = [[context activeUser] userDefaults];
[date setTimeZone: [ud timeZone]];
return date;
}
+15 -13
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/WOContext+SoObjects.h>
@@ -34,13 +33,15 @@
#import <EOControl/EOQualifier.h>
#import <SoObjects/Mailer/SOGoMailAccount.h>
#import <SoObjects/Mailer/SOGoDraftObject.h>
#import <SoObjects/Mailer/SOGoDraftsFolder.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSObject+Utilities.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoDraftObject.h>
#import <Mailer/SOGoDraftsFolder.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSObject+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "../Common/WODirectAction+SOGo.h"
@@ -189,13 +190,12 @@
SOGoMailFolder *inbox;
NGImap4Client *client;
NSString *inboxName;
NSUserDefaults *ud;
SOGoDomainDefaults *dd;
id infos;
float quota;
ud = [NSUserDefaults standardUserDefaults];
quota = [ud floatForKey: @"SOGoSoftQuotaRatio"];
dd = [[context activeUser] domainDefaults];
quota = [dd softQuotaRatio];
inbox = [co inboxFolderInContext: context];
inboxName = [NSString stringWithFormat: @"/%@", [inbox relativeImap4Name]];
client = [[inbox imap4Connection] client];
@@ -232,6 +232,7 @@
{
SOGoDraftsFolder *drafts;
SOGoDraftObject *newDraftMessage;
SOGoUserDefaults *ud;
NSString *urlBase, *url, *value, *signature;
NSArray *mailTo;
NSMutableDictionary *headers;
@@ -261,7 +262,8 @@
if (save)
[newDraftMessage setHeaders: headers];
signature = [[context activeUser] signature];
ud = [[context activeUser] userDefaults];
signature = [ud mailSignature];
if ([signature length])
{
[newDraftMessage
+5 -21
View File
@@ -23,7 +23,6 @@
#import <Foundation/NSFileManager.h>
#import <Foundation/NSKeyValueCoding.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoSubContext.h>
@@ -78,30 +77,15 @@
@implementation UIxMailEditor
static BOOL showInternetMarker = NO;
static NSDictionary *internetMailHeaders = nil;
static NSArray *infoKeys = nil;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
infoKeys = [[NSArray alloc] initWithObjects:
@"subject", @"to", @"cc", @"bcc",
@"from", @"replyTo", @"inReplyTo",
@"priority", nil];
/* Internet mail settings */
showInternetMarker = [ud boolForKey:@"SOGoShowInternetMarker"];
if (!showInternetMarker)
NSLog(@"Note: visual Internet marker on mail editor disabled "
@"(SOGoShowInternetMarker)");
internetMailHeaders =
[[ud dictionaryForKey:@"SOGoInternetMailHeaders"] copy];
NSLog (@"Note: specified %d headers for mails send via the Internet.",
[internetMailHeaders count]);
if (!infoKeys)
infoKeys = [[NSArray alloc] initWithObjects:
@"subject", @"to", @"cc", @"bcc",
@"from", @"replyTo", @"inReplyTo",
@"priority", nil];
}
- (id) init
+5 -6
View File
@@ -24,7 +24,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
@@ -319,21 +318,21 @@
{
SOGoMailFolder *co;
WOResponse *response;
NSUserDefaults *ud;
SOGoUserSettings *us;
NSMutableDictionary *mailSettings;
co = [self clientObject];
if ([NSStringFromClass ([co class]) isEqualToString: @"SOGoMailFolder"])
{
ud = [[context activeUser] userSettings];
mailSettings = [ud objectForKey: @"Mail"];
us = [[context activeUser] userSettings];
mailSettings = [us objectForKey: @"Mail"];
if (!mailSettings)
mailSettings = [NSMutableDictionary dictionary];
[ud setObject: mailSettings forKey: @"Mail"];
[us setObject: mailSettings forKey: @"Mail"];
[mailSettings setObject: [co traversalFromMailAccount]
forKey: [NSString stringWithFormat: @"%@Folder",
purpose]];
[ud synchronize];
[us synchronize];
response = [self responseWith204];
}
else
+1 -1
View File
@@ -32,7 +32,7 @@
{
NSArray *sortedUIDs; /* we always need to retrieve all anyway! */
NSArray *messages;
NSMutableArray *userDefinedOrder;
NSArray *columnsOrder;
unsigned firstMessageNumber;
id message;
EOQualifier *qualifier;
+40 -78
View File
@@ -32,7 +32,6 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/WOResponse.h>
@@ -45,44 +44,22 @@
#import <EOControl/EOQualifier.h>
#import <SoObjects/Mailer/NSString+Mail.h>
#import <SoObjects/Mailer/SOGoDraftsFolder.h>
#import <SoObjects/Mailer/SOGoMailFolder.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/Mailer/SOGoSentFolder.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/SOGoDateFormatter.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserDefaults.h>
#import <Mailer/NSString+Mail.h>
#import <Mailer/SOGoDraftsFolder.h>
#import <Mailer/SOGoMailFolder.h>
#import <Mailer/SOGoMailObject.h>
#import <Mailer/SOGoSentFolder.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/SOGoDateFormatter.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "UIxMailListView.h"
static NSArray *defaultColumnOrder = nil;
static NSArray *udColumnOrder = nil;
#define messagesPerPage 50
@implementation UIxMailListView
+ (void) initialize
{
if (!defaultColumnOrder)
{
defaultColumnOrder = [NSArray arrayWithObjects: @"Flagged",
@"Attachment", @"Subject", @"From",
@"Unread", @"Date", @"Priority", @"Size",
nil];
[defaultColumnOrder retain];
}
if (!udColumnOrder)
{
udColumnOrder = [[NSUserDefaults standardUserDefaults]
arrayForKey: @"SOGoMailListViewColumnsOrder"];
[udColumnOrder retain];
}
}
- (id) init
{
SOGoUser *user;
@@ -92,8 +69,8 @@ static NSArray *udColumnOrder = nil;
qualifier = nil;
user = [context activeUser];
ASSIGN (dateFormatter, [user dateFormatterInContext: context]);
ASSIGN (userTimeZone, [user timeZone]);
userDefinedOrder = nil;
ASSIGN (userTimeZone, [[user userDefaults] timeZone]);
columnsOrder = nil;
folderType = 0;
currentColumn = nil;
}
@@ -110,7 +87,7 @@ static NSArray *udColumnOrder = nil;
[dateFormatter release];
[userTimeZone release];
[currentColumn release];
[userDefinedOrder release];
[columnsOrder release];
[super dealloc];
}
@@ -504,21 +481,6 @@ static NSArray *udColumnOrder = nil;
return 1;
}
- (void) checkDefaultModulePreference
{
NSUserDefaults *ud;
NSString *pref;
ud = [[context activeUser] userDefaults];
pref = [ud stringForKey: @"SOGoUIxDefaultModule"];
if (pref && [pref isEqualToString: @"Last"])
{
[ud setObject: @"Mail" forKey: @"SOGoUIxLastModule"];
[ud synchronize];
}
}
- (NSArray *) messages
{
NSMutableArray *unsortedMsgs;
@@ -529,8 +491,6 @@ static NSArray *udColumnOrder = nil;
unsigned len, i, count;
NSRange r;
[self checkDefaultModulePreference];
if (!messages)
{
r = [self fetchBlock];
@@ -836,51 +796,53 @@ static NSArray *udColumnOrder = nil;
- (NSArray *) columnsDisplayOrder
{
NSMutableArray *testColumns;
NSArray *defaultsOrder;
NSUserDefaults *ud;
NSMutableArray *finalOrder, *invalid;
NSArray *available;
NSDictionary *metaData;
SOGoUserDefaults *ud;
unsigned int i;
if (!userDefinedOrder)
if (!columnsOrder)
{
ud = [[context activeUser] userSettings];
defaultsOrder = [ud arrayForKey: @"SOGoMailListViewColumnsOrder"];
if (![defaultsOrder count])
{
defaultsOrder = udColumnOrder;
if (![defaultsOrder count])
defaultsOrder = defaultColumnOrder;
}
userDefinedOrder = [defaultsOrder mutableCopy];
ud = [[context activeUser] userDefaults];
columnsOrder = [ud mailListViewColumnsOrder];
testColumns = [userDefinedOrder mutableCopy];
[testColumns removeObjectsInArray: defaultColumnOrder];
if ([testColumns count] > 0)
metaData = [self columnsMetaData];
invalid = [columnsOrder mutableCopy];
[invalid autorelease];
available = [metaData allKeys];
[invalid removeObjectsInArray: available];
if ([invalid count] > 0)
{
[self errorWithFormat: @"one or more column names specified in"
[self errorWithFormat: @"those column names specified in"
@" SOGoMailListViewColumnsOrder are invalid: '%@'",
[testColumns componentsJoinedByString: @"', '"]];
[invalid componentsJoinedByString: @"', '"]];
[self errorWithFormat: @" falling back on hardcoded column order"];
userDefinedOrder = [defaultColumnOrder mutableCopy];
columnsOrder = available;
}
[testColumns release];
finalOrder = [columnsOrder mutableCopy];
[finalOrder autorelease];
if ([self showToAddress])
{
i = [userDefinedOrder indexOfObject: @"From"];
i = [finalOrder indexOfObject: @"From"];
if (i != NSNotFound)
[userDefinedOrder replaceObjectAtIndex: i withObject: @"To"];
[finalOrder replaceObjectAtIndex: i withObject: @"To"];
}
else
{
i = [userDefinedOrder indexOfObject: @"To"];
i = [finalOrder indexOfObject: @"To"];
if (i != NSNotFound)
[userDefinedOrder replaceObjectAtIndex: i withObject: @"From"];
[finalOrder replaceObjectAtIndex: i withObject: @"From"];
}
columnsOrder = [[self columnsMetaData] objectsForKeys: finalOrder
notFoundMarker: @""];
[columnsOrder retain];
}
return [[self columnsMetaData] objectsForKeys: userDefinedOrder
notFoundMarker: @""];
return columnsOrder;
}
- (NSString *) columnsDisplayCount
+1 -1
View File
@@ -27,7 +27,7 @@
@interface UIxMailMainFrame : UIxComponent
{
NSUserDefaults *ud;
SOGoUserSettings *us;
NSMutableDictionary *moduleSettings;
}
+34 -28
View File
@@ -22,7 +22,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSUserDefaults.h>
#import <NGCards/NGVCard.h>
#import <NGCards/NGVCardReference.h>
@@ -39,15 +38,16 @@
#import <Contacts/SOGoContactFolders.h>
#import <Contacts/SOGoContactLDIFEntry.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/Mailer/SOGoMailAccount.h>
#import <SoObjects/Mailer/SOGoMailAccounts.h>
#import <SoObjects/SOGo/NSDictionary+URL.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserFolder.h>
#import <Mailer/SOGoMailObject.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
#import <SOGo/NSDictionary+URL.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserFolder.h>
#import <SOGoUI/UIxComponent.h>
#import "UIxMailMainFrame.h"
@@ -60,7 +60,6 @@
@end
@implementation UIxMailMainFrame
- (void) _setupContext
@@ -75,12 +74,12 @@
module = [clientObject nameInContainer];
ud = [activeUser userSettings];
moduleSettings = [ud objectForKey: module];
us = [activeUser userSettings];
moduleSettings = [us objectForKey: module];
if (!moduleSettings)
{
moduleSettings = [NSMutableDictionary dictionary];
[ud setObject: moduleSettings forKey: module];
[us setObject: moduleSettings forKey: module];
}
}
@@ -113,18 +112,11 @@
- (NSString *) defaultColumnsOrder
{
NSArray *defaultColumnsOrder;
NSUserDefaults *sud;
sud = [NSUserDefaults standardUserDefaults];
defaultColumnsOrder = [NSArray arrayWithArray: [sud arrayForKey: @"SOGoMailListViewColumnsOrder"]];
if ( [defaultColumnsOrder count] == 0 )
{
defaultColumnsOrder = [NSArray arrayWithObjects: @"Flagged", @"Attachment", @"Subject",
@"From", @"Unread", @"Date", @"Priority", nil];
}
return [defaultColumnsOrder jsonRepresentation];
SOGoDomainDefaults *dd;
dd = [[context activeUser] domainDefaults];
return [[dd mailListViewColumnsOrder] jsonRepresentation];
}
- (NSString *) pageFormURL
@@ -372,7 +364,7 @@
else
return [self responseWithStatus: 400];
[ud synchronize];
[us synchronize];
return [self responseWithStatus: 204];
}
@@ -389,9 +381,23 @@
[moduleSettings setObject: expandedFolders
forKey: @"ExpandedFolders"];
[ud synchronize];
[us synchronize];
return [self responseWithStatus: 204];
}
- (id) defaultAction
{
SOGoUserDefaults *ud;
ud = [[context activeUser] userDefaults];
if ([ud rememberLastModule])
{
[ud setLoginModule: @"Mail"];
[ud synchronize];
}
return [super defaultAction];
}
@end /* UIxMailMainFrame */
+6 -5
View File
@@ -23,8 +23,9 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSEnumerator.h>
#import <NGObjWeb/WORequest.h>
#import <SoObjects/Mailer/SOGoMailFolder.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailFolder.h>
#import <SOGo/SOGoPermissions.h>
#import "UIxMailUserRightsEditor.h"
@@ -32,11 +33,11 @@
- (BOOL) conformsToRFC4314
{
SOGoMailFolder *co;
SOGoMailAccount *mailAccount;
co = [self clientObject];
mailAccount = [[self clientObject] mailAccountFolder];
return ([[co class] imapAclStyle] == rfc4314);
return ([mailAccount imapAclStyle] == rfc4314);
}
- (void) setUserCanReadMails: (BOOL) userCanReadMails
+28 -40
View File
@@ -20,7 +20,6 @@
*/
#import <Foundation/NSException.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
@@ -51,18 +50,11 @@ static NSString *mailETag = nil;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
if ([ud boolForKey:@"SOGoDontUseETagsForMailViewer"])
NSLog(@"Note: usage of constant etag for mailer viewer is disabled.");
else
{
mailETag = [[NSString alloc] initWithFormat:@"\"imap4url_%d_%d_%03d\"",
UIX_MAILER_MAJOR_VERSION,
UIX_MAILER_MINOR_VERSION,
UIX_MAILER_SUBMINOR_VERSION];
NSLog(@"Note: using constant etag for mail viewer: '%@'", mailETag);
}
mailETag = [[NSString alloc] initWithFormat:@"\"imap4url_%d_%d_%03d\"",
UIX_MAILER_MAJOR_VERSION,
UIX_MAILER_MINOR_VERSION,
UIX_MAILER_SUBMINOR_VERSION];
NSLog(@"Note: using constant etag for mail viewer: '%@'", mailETag);
}
/* accessors */
@@ -146,33 +138,30 @@ static NSString *mailETag = nil;
NSString *s;
/* check etag to see whether we really must rerender */
if (mailETag)
/*
Note: There is one thing which *can* change for an existing message,
those are the IMAP4 flags (and annotations, which we do not use).
Since we don't render the flags, it should be OK, if this changes
we must embed the flagging into the etag.
*/
s = [[context request] headerForKey: @"if-none-match"];
if (s)
{
/*
Note: There is one thing which *can* change for an existing message,
those are the IMAP4 flags (and annotations, which we do not use).
Since we don't render the flags, it should be OK, if this changes
we must embed the flagging into the etag.
*/
s = [[context request] headerForKey: @"if-none-match"];
if (s)
{
if ([s rangeOfString:mailETag].length > 0) /* not perfectly correct */
{
/* client already has the proper entity */
// [self logWithFormat:@"MATCH: %@ (tag %@)", s, mailETag];
if (![[self clientObject] doesMailExist]) {
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
reason:@"message got deleted"];
}
if ([s rangeOfString:mailETag].length > 0) /* not perfectly correct */
{
/* client already has the proper entity */
// [self logWithFormat:@"MATCH: %@ (tag %@)", s, mailETag];
if (![[self clientObject] doesMailExist]) {
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
reason:@"message got deleted"];
}
response = [context response];
[response setStatus: 304 /* Not Modified */];
response = [context response];
[response setStatus: 304 /* Not Modified */];
return response;
}
}
return response;
}
}
if (![self message]) // TODO: redirect to proper error
@@ -211,8 +200,7 @@ static NSString *mailETag = nil;
request = [_ctx request];
if (mailETag != nil)
[[_ctx response] setHeader:mailETag forKey:@"etag"];
[[_ctx response] setHeader:mailETag forKey:@"etag"];
mctx = [[UIxMailRenderingContext alloc] initWithViewer: self
context: _ctx];
+18 -27
View File
@@ -20,7 +20,6 @@
*/
#import <Foundation/NSException.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOContext.h>
@@ -33,13 +32,13 @@
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SoObjects/SOGo/SOGoWebAuthenticator.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoWebAuthenticator.h>
#import "SOGoRootPage.h"
static NSArray *supportedLanguages = nil;
@interface SOGoRootPage (crashAdditions)
- (void) segfault;
@@ -48,12 +47,6 @@ static NSArray *supportedLanguages = nil;
@implementation SOGoRootPage
+ (void) initialize
{
if (!supportedLanguages)
supportedLanguages = [NSArray arrayWithObjects: @"Czech", @"Welsh", @"English", @"Spanish", @"French", @"German", @"Italian", @"Hungarian", @"Dutch", @"BrazilianPortuguese", @"Russian", @"Swedish", nil];
}
/* accessors */
- (NSString *) connectURL
@@ -68,9 +61,10 @@ static NSArray *supportedLanguages = nil;
WORequest *request;
WOCookie *authCookie;
SOGoWebAuthenticator *auth;
SOGoUser *user;
SOGoUserDefaults *ud;
NSString *cookieValue, *cookieString;
NSString *userName, *password, *language;
NSArray *supportedLanguages;
auth = [[WOApplication application]
authenticatorInContext: context];
@@ -93,12 +87,14 @@ static NSArray *supportedLanguages = nil;
[authCookie setIsSecure: YES]; */
[response addCookie: authCookie];
supportedLanguages = [[SOGoSystemDefaults sharedSystemDefaults]
supportedLanguages];
if (language && [supportedLanguages containsObject: language])
{
user = [SOGoUser userWithLogin: userName roles: nil];
[[user userDefaults] setObject: language forKey: @"Language"];
[[user userDefaults] synchronize];
[user invalidateLanguage];
ud = [[SOGoUser userWithLogin: userName roles: nil]
userDefaults];
[ud setLanguage: language];
[ud synchronize];
}
}
else
@@ -160,11 +156,7 @@ static NSArray *supportedLanguages = nil;
- (NSString *) loginSuffix
{
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
return [ud stringForKey: @"SOGoLoginSuffix"];
return [[SOGoSystemDefaults sharedSystemDefaults] loginSuffix];
}
- (BOOL) hasLoginSuffix
@@ -184,13 +176,13 @@ static NSArray *supportedLanguages = nil;
- (NSArray *) languages
{
return supportedLanguages;
return [[SOGoSystemDefaults sharedSystemDefaults] supportedLanguages];
}
- (NSString *) language
{
return [SOGoUser language];
}
// - (NSString *) language
// {
// return [SOGoUser language];
// }
- (NSString *) languageText
{
@@ -213,5 +205,4 @@ static NSArray *supportedLanguages = nil;
return aString;
}
@end /* SOGoRootPage */
+22 -58
View File
@@ -26,7 +26,6 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOCookie.h>
@@ -36,74 +35,43 @@
#import <NGExtensions/NSObject+Logs.h>
#import <Appointments/SOGoFreeBusyObject.h>
#import <SoObjects/SOGo/SOGoUserManager.h>
#import <SoObjects/SOGo/SOGoWebAuthenticator.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoUserFolder.h>
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/SOGoWebAuthenticator.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserFolder.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGoUI/UIxComponent.h>
#define intervalSeconds 900 /* 15 minutes */
static NSString *defaultModule = nil;
static NSString *LDAPContactInfoAttribute = nil;
@interface SOGoUserHomePage : UIxComponent
@end
@implementation SOGoUserHomePage
+ (void) initialize
{
NSUserDefaults *ud;
if (!defaultModule)
{
ud = [NSUserDefaults standardUserDefaults];
defaultModule = [ud stringForKey: @"SOGoUIxDefaultModule"];
if (defaultModule)
{
if (!([defaultModule isEqualToString: @"Calendar"]
|| [defaultModule isEqualToString: @"Contacts"]
|| [defaultModule isEqualToString: @"Mail"]))
{
[self logWithFormat: @"default module '%@' not accepted (must be"
@"'Calendar', 'Contacts' or 'Mail')", defaultModule];
defaultModule = @"Calendar";
}
}
else
defaultModule = @"Calendar";
[self logWithFormat: @"default module set to '%@'", defaultModule];
[defaultModule retain];
LDAPContactInfoAttribute = [ud stringForKey: @"SOGoLDAPContactInfoAttribute"];
[LDAPContactInfoAttribute retain];
}
}
- (id <WOActionResults>) defaultAction
{
SOGoUserFolder *co;
NSUserDefaults *ud;
NSString *userDefinedModule;
NSString *loginModule;
SOGoUserDefaults *ud;
NSURL *moduleURL;
ud = [[context activeUser] userDefaults];
userDefinedModule = [ud stringForKey: @"SOGoUIxDefaultModule"];
if (userDefinedModule)
loginModule = [ud loginModule];
if (!([loginModule isEqualToString: @"Calendar"]
|| [loginModule isEqualToString: @"Contacts"]
|| [loginModule isEqualToString: @"Mail"]))
{
if ([userDefinedModule isEqualToString: @"Last"])
userDefinedModule = [ud stringForKey: @"SOGoUIxLastModule"];
[self errorWithFormat: @"login module '%@' not accepted (must be"
@"'Calendar', 'Contacts' or 'Mail')", loginModule];
loginModule = @"Calendar";
}
if (!userDefinedModule)
userDefinedModule = defaultModule;
co = [self clientObject];
moduleURL = [NSURL URLWithString: userDefinedModule
moduleURL = [NSURL URLWithString: loginModule
relativeToURL: [co soURL]];
return [self redirectToLocation: [moduleURL absoluteString]];
@@ -219,7 +187,7 @@ static NSString *LDAPContactInfoAttribute = nil;
co = [self clientObject];
user = [context activeUser];
uTZ = [user timeZone];
uTZ = [[user userDefaults] timeZone];
queryDay = [self queryParameterForKey: @"sday"];
if ([queryDay length])
@@ -338,13 +306,8 @@ static NSString *LDAPContactInfoAttribute = nil;
// We do NOT return the current authenticated user.
if (![uid isEqualToString: login])
{
if ([LDAPContactInfoAttribute length])
{
contactInfo = [contact objectForKey: [LDAPContactInfoAttribute lowercaseString]];
if (!contactInfo)
contactInfo = @"";
}
else
contactInfo = [contact objectForKey: @"c_info"];
if (!contactInfo)
contactInfo = @"";
[responseString appendFormat: @"%@:%@:%@:%@\n", uid,
[contact objectForKey: @"cn"],
@@ -359,7 +322,7 @@ static NSString *LDAPContactInfoAttribute = nil;
- (id <WOActionResults>) usersSearchAction
{
NSString *contact;
NSString *contact, *domain;
id <WOActionResults> result;
SOGoUserManager *um;
@@ -367,6 +330,7 @@ static NSString *LDAPContactInfoAttribute = nil;
contact = [self queryParameterForKey: @"search"];
if ([contact length])
{
domain = [[context activeUser] domain];
result
= [self _usersResponseForResults: [um fetchUsersMatching: contact]];
}
+11 -10
View File
@@ -20,47 +20,48 @@
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WODirectAction.h>
#import <NGObjWeb/WOResponse.h>
#import <SoObjects/SOGo/NSObject+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SOGo/NSObject+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserSettings.h>
#import <SOGo/SOGoUserProfile.h>
#import "UIxJSONPreferences.h"
@implementation UIxJSONPreferences
- (WOResponse *) _makeResponse: (NSUserDefaults *) defaults
- (WOResponse *) _makeResponse: (SOGoUserProfile *) profile
{
WOResponse *response;
response = [context response];
[response setHeader: @"text/plain; charset=utf-8"
forKey: @"content-type"];
[response appendContentString: [defaults jsonRepresentation]];
[response appendContentString: [profile jsonRepresentation]];
return response;
}
- (WOResponse *) jsonDefaultsAction
{
NSUserDefaults *defaults;
SOGoUserDefaults *defaults;
defaults = [[context activeUser] userDefaults];
return [self _makeResponse: defaults];
return [self _makeResponse: [defaults source]];
}
- (WOResponse *) jsonSettingsAction
{
NSUserDefaults *settings;
SOGoUserSettings *settings;
settings = [[context activeUser] userSettings];
return [self _makeResponse: settings];
return [self _makeResponse: [settings source]];
}
@end
+2 -3
View File
@@ -26,7 +26,7 @@
#import <SOGoUI/UIxComponent.h>
@class NSString;
@class NSUserDefaults;
@class SOGoUserDefaults;
@class SOGoUser;
@@ -35,9 +35,8 @@
id item;
SOGoUser *user;
NSDictionary *locale;
NSUserDefaults *userDefaults;
SOGoUserDefaults *userDefaults;
NSCalendarDate *today;
NSMutableArray *hours;
NSArray *daysOfWeek, *daysBetweenResponsesList;
NSMutableDictionary *vacationOptions, *forwardOptions;
BOOL hasChanged, composeMessageTypeHasChanged;

Some files were not shown because too many files have changed in this diff Show More