mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-28 17:57:38 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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)/ \
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
- (BOOL) boolValue;
|
||||
#endif
|
||||
|
||||
- (int) timeValue;
|
||||
|
||||
// LDIF
|
||||
- (BOOL) _isLDIFSafe;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+501
-492
File diff suppressed because it is too large
Load Diff
@@ -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>"];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
@interface SQLSource : NSObject <SOGoSource>
|
||||
{
|
||||
NSString *_sourceID;
|
||||
NSString *_domain;
|
||||
NSString *_domainAttribute;
|
||||
NSArray *_mailFields;
|
||||
NSString *_userPasswordAlgorithm;
|
||||
NSURL *_viewURL;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user