Monotone-Parent: ec44ffcb951f3db4e0041a44e56a9f0d5df4ef3b

Monotone-Revision: 4363c5abe7a96c858bbccbbad1061ca3229e0217

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2010-08-06T14:25:59
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2010-08-06 14:25:59 +00:00
parent 44a7a9b099
commit b880434179
10 changed files with 263 additions and 226 deletions
+41
View File
@@ -1,5 +1,46 @@
2010-08-06 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Mailer/SOGoMailForward.m (-signature): same as below.
* UI/MailerUI/UIxMailAccountActions.m (-composeAction): same as below.
* SoObjects/Mailer/SOGoDraftObject.m (-fetchMailForForwarding):
the signature is now taken from the original mail's corresponding
account.
* SoObjects/Mailer/SOGoMailFolder.m
(-copyUIDs:toFolder:inContext:): we now ensure that the operation
is not attempted on two separate accounts.
(-httpURLForAdvisoryToUser): the returned mail account is now
always "0".
* SoObjects/Mailer/SOGoMailBaseObject.m (-imap4URL): we now add
the "tls=YES" url parameter if the corresponding account
encryption is set to "tls".
(-imap4Login): removed useless method.
(-imap4PasswordRenewed:): now a proxy to the same method on the
instance account folder.
* SoObjects/Mailer/SOGoMailAccount.m (-identities, -signature)
(encryption): new helper methods that return the corresponding key
in the appropriate mail account dictionary.
(-_migrateFolderWithPurpose:): moved method in SOGoMailAccount.m.
(-_userFolderNameWithPurpose): rewrote method to make use of the
mail account dictionaries. Fallback on the main account of the
auxiliary ones do not have the required entry.
(-imap4PasswordRenewed:): moved method from SOGoMailBaseObject.m
and use the "password" entry in auxiliary account dicts depending
on "nameInContainer".
(-imap4LoginFromHTTP, -imap4Login): removed useless methods.
* SoObjects/SOGo/SOGoUser.m (-mailAccounts): we now conditionnally
append the array of auxiliary user accounts, if enabled in the
domain defaults.
(-_appendSystemMailAccount): the user main signature and the
sent, drafts, trash folder location are now stored in the account
dictionaries. Added migration code from us to ud from
SOGoMailAccount.m.
* SoObjects/SOGo/SOGoDomainDefaults.m
(-mailAuxiliaryUserAccountsEnabled): new method returning a BOOL
describing whether the domain users can access auxiliary mail
+1 -1
View File
@@ -722,7 +722,7 @@ static NSString *userAgent = nil;
{
// TODO: use subject for filename?
// error = [newDraft saveAttachment:content withName:@"forward.eml"];
signature = [ud mailSignature];
signature = [[self mailAccountFolder] signature];
if ([signature length])
[self setText: [NSString stringWithFormat: @"\n-- \n%@", signature]];
attachment = [NSDictionary dictionaryWithObjectsAndKeys:
+4
View File
@@ -63,6 +63,10 @@ typedef enum {
- (BOOL) supportsQuotas;
- (BOOL) updateFilters;
- (NSArray *) identities;
- (NSString *) signature;
- (NSString *) encryption;
/* folder pathes */
- (NSArray *) allFolderPaths;
+71 -84
View File
@@ -40,6 +40,7 @@
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoAuthenticator.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
@@ -468,31 +469,6 @@ static NSString *sieveScriptName = @"sogo";
/* IMAP4 */
- (NSString *) imap4LoginFromHTTP
{
WORequest *rq;
NSString *s;
NSArray *creds;
rq = [context request];
s = [rq headerForKey:@"x-webobjects-remote-user"];
if ([s length] > 0)
return s;
if ((s = [rq headerForKey:@"authorization"]) == nil) {
/* no basic auth */
return nil;
}
creds = [SoHTTPAuthenticator parseCredentials:s];
if ([creds count] < 2)
/* somehow invalid */
return nil;
return [creds objectAtIndex:0]; /* the user */
}
- (NSDictionary *) _mailAccount
{
NSDictionary *mailAccount;
@@ -506,6 +482,36 @@ static NSString *sieveScriptName = @"sogo";
return mailAccount;
}
- (NSArray *) identities
{
return [[self _mailAccount] objectForKey: @"identities"];
}
- (NSString *) signature
{
NSArray *identities;
NSString *signature;
identities = [self identities];
if ([identities count] > 0)
signature = [[identities objectAtIndex: 0] objectForKey: @"signature"];
else
signature = nil;
return signature;
}
- (NSString *) encryption
{
NSString *encryption;
encryption = [[self _mailAccount] objectForKey: @"encryption"];
if (![encryption length])
encryption = @"none";
return encryption;
}
- (NSMutableString *) imap4URLString
{
NSMutableString *imap4URLString;
@@ -546,9 +552,33 @@ static NSString *sieveScriptName = @"sogo";
return [NSMutableString string];
}
- (NSString *) imap4Login
- (NSString *) imap4PasswordRenewed: (BOOL) renewed
{
return [[self imap4URL] user];
/*
Extract password from basic authentication.
*/
NSURL *imapURL;
NSString *password;
if ([nameInContainer isEqualToString: @"0"])
{
imapURL = [self imap4URL];
password = [[self authenticatorInContext: context]
imapPasswordInContext: context
forServer: [imapURL host]
forceRenew: renewed];
if (!password)
[self errorWithFormat: @"no IMAP4 password available"];
}
else
{
password = [[self _mailAccount] objectForKey: @"password"];
if (!password)
password = @"";
}
return password;
}
/* name lookup */
@@ -604,70 +634,27 @@ static NSString *sieveScriptName = @"sogo";
return inboxFolderName;
}
- (BOOL) _migrateFolderWithPurpose: (NSString *) purpose
withName: (NSString *) folderName
{
SOGoUserDefaults *ud;
NSString *methodName;
SEL methodSel;
BOOL rc;
ud = [[context activeUser] userDefaults];
methodName = [NSString stringWithFormat: @"set%@FolderName:", purpose];
methodSel = NSSelectorFromString (methodName);
if ([ud respondsToSelector: methodSel])
{
[ud performSelector: methodSel withObject: folderName];
[ud synchronize];
rc = YES;
}
else
{
[self errorWithFormat: @"method '%@' not available with user defaults"
@" object, folder migration fails", methodName];
rc = NO;
}
return rc;
}
- (NSString *) _userFolderNameWithPurpose: (NSString *) purpose
{
SOGoUser *user;
SOGoUserSettings *us;
SOGoUserDefaults *ud;
NSMutableDictionary *mailSettings;
NSString *folderName, *key, *methodName;
SEL methodSel;
NSArray *accounts;
int accountIdx;
NSDictionary *account;
NSString *folderName;
folderName = nil;
user = [context activeUser];
/* migration part: */
us = [user userSettings];
mailSettings = [us objectForKey: @"Mail"];
if (mailSettings)
user = [SOGoUser userWithLogin: [self ownerInContext: nil]];
accounts = [user mailAccounts];
accountIdx = [nameInContainer intValue];
account = [accounts objectAtIndex: accountIdx];
folderName = [[account objectForKey: @"mailboxes"]
objectForKey: purpose];
if (!folderName && accountIdx > 0)
{
key = [NSString stringWithFormat: @"%@Folder", purpose];
folderName = [mailSettings objectForKey: key];
if ([folderName length]
&& [self _migrateFolderWithPurpose: purpose withName: folderName])
{
[mailSettings removeObjectForKey: key];
[us synchronize];
folderName = nil;
}
}
else
folderName = nil;
if (!folderName)
{
ud = [[context activeUser] userDefaults];
methodName = [NSString stringWithFormat: @"%@FolderName",
[purpose lowercaseString]];
methodSel = NSSelectorFromString (methodName);
folderName = [ud performSelector: methodSel];
account = [accounts objectAtIndex: 0];
folderName = [[account objectForKey: @"mailboxes"]
objectForKey: purpose];
}
return folderName;
-1
View File
@@ -69,7 +69,6 @@
- (NSMutableString *) traversalFromMailAccount;
- (NSURL *) imap4URL;
- (NSString *) imap4Login;
- (NSString *) imap4PasswordRenewed: (BOOL) renew;
- (void) flushMailCaches;
+14 -31
View File
@@ -30,8 +30,7 @@
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSURL+misc.h>
#import <SOGo/SOGoAuthenticator.h>
#import "SOGoMailAccount.h"
#import "SOGoMailManager.h"
#import "SOGoMailBaseObject.h"
@@ -187,44 +186,28 @@ static BOOL debugOn = YES;
- (NSURL *) imap4URL
{
SOGoMailAccount *account;
NSString *urlString;
/* this could probably be handled better from NSURL but it's buggy in
GNUstep */
if (!imap4URL)
imap4URL = [[NSURL alloc] initWithString: [self imap4URLString]];
{
account = [self mailAccountFolder];
if ([[account encryption] isEqualToString: @"tls"])
urlString = [NSString stringWithFormat: @"%@?tls=YES",
[self imap4URLString]];
else
urlString = [self imap4URLString];
imap4URL = [[NSURL alloc] initWithString: urlString];
}
return imap4URL;
}
- (NSString *) imap4Login
{
if (![container respondsToSelector:_cmd])
return nil;
return [container imap4Login];
}
- (NSString *) imap4PasswordRenewed: (BOOL) renewed
{
/*
Extract password from basic authentication.
TODO: we might want to
a) move the primary code to SOGoMailAccount
b) cache the password
*/
NSURL *imapURL;
NSString *password;
imapURL = [[self mailAccountFolder] imap4URL];
password = [[self authenticatorInContext: context]
imapPasswordInContext: context
forServer: [imapURL host]
forceRenew: renewed];
if (!password)
[self errorWithFormat: @"no IMAP4 password available"];
return password;
return [[self mailAccountFolder] imap4PasswordRenewed: renewed];
}
- (NSMutableString *) traversalFromMailAccount
+38 -25
View File
@@ -447,7 +447,7 @@ static NSString *defaultUserID = @"anyone";
inContext: (id) localContext
{
NSArray *folders;
NSString *currentFolderName;
NSString *currentFolderName, *currentAccountName;
NSMutableString *imapDestinationFolder;
NGImap4Client *client;
id result;
@@ -458,31 +458,45 @@ static NSString *defaultUserID = @"anyone";
folders = [[destinationFolder componentsSeparatedByString: @"/"]
resultsOfSelector: @selector (fromCSSIdentifier)];
max = [folders count];
for (count = 2; count < max; count++)
if (max > 1)
{
currentFolderName
= [[folders objectAtIndex: count] substringFromIndex: 6];
[imapDestinationFolder appendFormat: @"/%@", currentFolderName];
currentAccountName = [[self mailAccountFolder] nameInContainer];
if ([[folders objectAtIndex: 1] isEqualToString: currentAccountName])
{
for (count = 2; count < max; count++)
{
currentFolderName
= [[folders objectAtIndex: count] substringFromIndex: 6];
[imapDestinationFolder appendFormat: @"/%@", currentFolderName];
}
client = [[self imap4Connection] client];
[imap4 selectFolder: [self imap4URL]];
// We make sure the destination IMAP folder exist, if not, we create it.
result = [[client status: imapDestinationFolder
flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]
objectForKey: @"result"];
if (![result boolValue])
result = [[self imap4Connection] createMailbox: imapDestinationFolder
atURL: [[self mailAccountFolder] imap4URL]];
if (!result || [result boolValue])
result = [client copyUids: uids toFolder: imapDestinationFolder];
if ([[result valueForKey: @"result"] boolValue])
result = nil;
else
result = [NSException exceptionWithHTTPStatus: 500
reason: @"Couldn't copy UIDs."];
}
else
result = [NSException exceptionWithHTTPStatus: 500
reason: @"Cannot copy messages across different accounts."];
}
client = [[self imap4Connection] client];
[imap4 selectFolder: [self imap4URL]];
// We make sure the destination IMAP folder exist, if not, we create it.
result = [[client status: imapDestinationFolder
flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]
objectForKey: @"result"];
if (![result boolValue])
result = [[self imap4Connection] createMailbox: imapDestinationFolder
atURL: [[self mailAccountFolder] imap4URL]];
if (!result || [result boolValue])
result = [client copyUids: uids toFolder: imapDestinationFolder];
if ([[result valueForKey: @"result"] boolValue])
result = nil;
else
result = [NSException exceptionWithHTTPStatus: 500 reason: @"Couldn't copy UIDs."];
result = [NSException exceptionWithHTTPStatus: 500
reason: @"Invalid destination."];
return result;
}
@@ -1061,9 +1075,8 @@ static NSString *defaultUserID = @"anyone";
{
thisAccount = [self mailAccountFolder];
mailAccount = [[user mailAccounts] objectAtIndex: 0];
url = [NSString stringWithFormat: @"%@/%@%@",
url = [NSString stringWithFormat: @"%@/0%@",
[self soURLToBaseContainerForUser: uid],
[mailAccount objectForKey: @"name"],
otherUsersPath];
}
else
+2 -1
View File
@@ -29,6 +29,7 @@
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "SOGoMailAccount.h"
#import "SOGoMailObject+Draft.h"
#import "SOGoMailForward.h"
@@ -221,7 +222,7 @@
SOGoUserDefaults *ud;
ud = [[context activeUser] userDefaults];
signature = [ud mailSignature];
signature = [[sourceMail mailAccountFolder] signature];
if ([signature length])
mailSignature = [NSString stringWithFormat: @"-- \n%@", signature];
else
+91 -79
View File
@@ -436,11 +436,73 @@
}
/* mail */
- (BOOL) _migrateFolderWithPurpose: (NSString *) purpose
withName: (NSString *) folderName
{
NSString *methodName;
SEL methodSel;
BOOL rc;
[self userDefaults];
methodName = [NSString stringWithFormat: @"set%@FolderName:", purpose];
methodSel = NSSelectorFromString (methodName);
if ([_defaults respondsToSelector: methodSel])
{
[_defaults performSelector: methodSel withObject: folderName];
rc = YES;
}
else
{
[self errorWithFormat: @"method '%@' not available with user defaults"
@" object, folder migration fails", methodName];
rc = NO;
}
return rc;
}
- (void) _migrateFolderSettings
{
NSMutableDictionary *mailSettings;
NSString *folderName, *key;
BOOL migrated;
NSString **purpose;
NSString *purposes[] = { @"Drafts", @"Sent", @"Trash", nil };
[self userSettings];
mailSettings = [_settings objectForKey: @"Mail"];
if (mailSettings)
{
migrated = NO;
purpose = purposes;
while (*purpose)
{
key = [NSString stringWithFormat: @"%@Folder", purpose];
folderName = [mailSettings objectForKey: key];
if ([folderName length]
&& [self _migrateFolderWithPurpose: *purpose
withName: folderName])
{
migrated = YES;
[mailSettings removeObjectForKey: key];
folderName = nil;
}
purpose++;
}
if (migrated)
{
[_settings synchronize];
[self userDefaults];
[_defaults synchronize];
}
}
}
- (void) _appendSystemMailAccount
{
NSMutableDictionary *mailAccount, *identity;
NSMutableDictionary *mailAccount, *identity, *mailboxes;
NSMutableArray *identities;
NSString *fullName, *imapLogin, *imapServer;
NSString *fullName, *imapLogin, *imapServer, *signature;
NSArray *mails;
unsigned int count, max;
@@ -451,6 +513,7 @@
imapServer = [self _fetchFieldForUser: @"c_imaphostname"];
if (!imapServer)
imapServer = [[self domainDefaults] imapServer];
[mailAccount setObject: imapLogin forKey: @"userName"];
[mailAccount setObject: imapServer forKey: @"serverName"];
@@ -469,6 +532,9 @@
fullName = login;
[identity setObject: fullName forKey: @"fullName"];
[identity setObject: [mails objectAtIndex: count] forKey: @"email"];
signature = [[self userDefaults] mailSignature];
if (signature)
[identity setObject: signature forKey: @"signature"];
[identities addObject: identity];
[identity release];
}
@@ -477,16 +543,38 @@
[mailAccount setObject: identities forKey: @"identities"];
[identities release];
[mailAccounts addObject: mailAccount];
mailboxes = [NSMutableDictionary new];
[self userDefaults];
[self _migrateFolderSettings];
[mailboxes setObject: [_defaults draftsFolderName]
forKey: @"Drafts"];
[mailboxes setObject: [_defaults sentFolderName]
forKey: @"Sent"];
[mailboxes setObject: [_defaults trashFolderName]
forKey: @"Trash"];
[mailAccount setObject: mailboxes forKey: @"mailboxes"];
[mailboxes release];
[mailAccounts addObject: mailAccount];
[mailAccount release];
}
- (NSArray *) mailAccounts
{
NSArray *auxAccounts;
if (!mailAccounts)
{
mailAccounts = [NSMutableArray new];
[self _appendSystemMailAccount];
if ([[self domainDefaults] mailAuxiliaryUserAccountsEnabled])
{
auxAccounts = [[self userDefaults] auxiliaryMailAccounts];
if (auxAccounts)
[mailAccounts addObjectsFromArray: auxAccounts];
}
}
return mailAccounts;
@@ -509,60 +597,6 @@
return mailAccount;
}
/*
@interface SOGoMailIdentity : NSObject
{
NSString *name;
NSString *email;
NSString *replyTo;
NSString *organization;
NSString *signature;
NSString *vCard;
NSString *sentFolderName;
NSString *sentBCC;
NSString *draftsFolderName;
NSString *templatesFolderName;
struct
{
int composeHTML:1;
int reserved:31;
} idFlags;
}
- (void) setName: (NSString *) _value;
- (NSString *) name;
- (void) setEmail: (NSString *) _value;
- (NSString *) email;
- (void) setReplyTo: (NSString *) _value;
- (NSString *) replyTo;
- (void) setOrganization: (NSString *) _value;
- (NSString *) organization;
- (void) setSignature: (NSString *) _value;
- (NSString *) signature;
- (BOOL) hasSignature;
- (void) setVCard: (NSString *) _value;
- (NSString *) vCard;
- (BOOL) hasVCard;
- (void) setSentFolderName: (NSString *) _value;
- (NSString *) sentFolderName;
- (void) setSentBCC: (NSString *) _value;
- (NSString *) sentBCC;
- (void) setDraftsFolderName: (NSString *) _value;
- (NSString *) draftsFolderName;
- (void) setTemplatesFolderName: (NSString *) _value;
- (NSString *) templatesFolderName;
@end */
- (NSArray *) allIdentities
{
NSArray *identities;
@@ -607,28 +641,6 @@
ignoringRights: YES];
}
// - (id) schedulingCalendarInContext: (id) _ctx
// {
// /* Note: watch out for cyclic references */
// id folder;
// folder = [(WOContext *)_ctx objectForKey:@"ActiveUserCalendar"];
// if (folder != nil)
// return [folder isNotNull] ? folder : nil;
// folder = [self homeFolderInContext:_ctx];
// if ([folder isKindOfClass:[NSException class]])
// return folder;
// folder = [folder lookupName:@"Calendar" inContext:_ctx acquire:NO];
// if ([folder isKindOfClass:[NSException class]])
// return folder;
// [(WOContext *)_ctx setObject:folder ? folder : [NSNull null]
// forKey:@"ActiveUserCalendar"];
// return folder;
// }
- (NSArray *) rolesForObject: (NSObject *) object
inContext: (WOContext *) context
{
+1 -4
View File
@@ -41,7 +41,6 @@
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "../Common/WODirectAction+SOGo.h"
@@ -232,7 +231,6 @@
{
SOGoDraftsFolder *drafts;
SOGoDraftObject *newDraftMessage;
SOGoUserDefaults *ud;
NSString *urlBase, *url, *value, *signature;
NSArray *mailTo;
NSMutableDictionary *headers;
@@ -262,8 +260,7 @@
if (save)
[newDraftMessage setHeaders: headers];
ud = [[context activeUser] userDefaults];
signature = [ud mailSignature];
signature = [[self clientObject] signature];
if ([signature length])
{
[newDraftMessage