mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-16 02:38:51 +00:00
See ChangeLog
Monotone-Parent: baa7bc0bc74871932c7f4e4d759f25a216d0c939 Monotone-Revision: 25a398b968eb4c84157efcd698facc74c5738e07 Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2009-10-09T21:01:54 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2009-10-08 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* Added filters support (Vacation and Forward) which
|
||||
can be enabled using the SOGoVacationEnabled and
|
||||
SOGoForwardEnabled defaults. One Sieve right now is
|
||||
support and we assume the Sieve server is the same
|
||||
as the IMAP server, running on port 2000.
|
||||
|
||||
2009-10-08 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/LDAPSource.m (-_searchAttributes): we already
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
Copyright (C) 2009 Inverse inc.
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
This file is part of SOGo.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
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.
|
||||
|
||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
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
|
||||
License along with SOGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
@@ -52,6 +53,7 @@
|
||||
- (void) setAccountName: (NSString *) newAccountName;
|
||||
|
||||
- (BOOL) supportsQuotas;
|
||||
- (BOOL) updateFilters;
|
||||
|
||||
/* folder pathes */
|
||||
|
||||
@@ -68,7 +70,6 @@
|
||||
|
||||
- (NSString *) inboxFolderNameInContext: (id)_ctx;
|
||||
- (NSString *) draftsFolderNameInContext: (id)_ctx;
|
||||
// - (NSString *) sieveFolderNameInContext: (id)_ctx;
|
||||
- (NSString *) sentFolderNameInContext: (id)_ctx;
|
||||
- (NSString *) trashFolderNameInContext: (id)_ctx;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
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
|
||||
License along with SOGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
@@ -29,12 +29,14 @@
|
||||
#import <NGObjWeb/SoHTTPAuthenticator.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGStreams/NGInternetSocketAddress.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
#import <NGImap4/NGImap4Connection.h>
|
||||
#import <NGImap4/NGImap4Client.h>
|
||||
#import <NGImap4/NGImap4Context.h>
|
||||
#import <NGImap4/NGSieveClient.h>
|
||||
|
||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
@@ -52,11 +54,12 @@
|
||||
static NSArray *rootFolderNames = nil;
|
||||
static NSString *inboxFolderName = @"INBOX";
|
||||
static NSString *draftsFolderName = @"Drafts";
|
||||
static NSString *sieveFolderName = @"Filters";
|
||||
static NSString *sentFolderName = nil;
|
||||
static NSString *trashFolderName = nil;
|
||||
static NSString *sharedFolderName = @""; // TODO: add English default
|
||||
static NSString *sharedFolderName = @""; // TODO: add English default
|
||||
static NSString *otherUsersFolderName = @""; // TODO: add English default
|
||||
static NSString *sieveScriptName = @"sogo";
|
||||
|
||||
static BOOL defaultShowSubscribedFoldersOnly = NO;
|
||||
// this is temporary, until we allow users to manage their own accounts
|
||||
static NSString *fallbackIMAP4Server = nil;
|
||||
@@ -91,15 +94,10 @@ static NSString *fallbackIMAP4Server = nil;
|
||||
|
||||
NSLog(@"Note: using shared-folders name: '%@'", sharedFolderName);
|
||||
NSLog(@"Note: using other-users-folders name: '%@'", otherUsersFolderName);
|
||||
if ([ud boolForKey: @"SOGoEnableSieveFolder"])
|
||||
rootFolderNames = [[NSArray alloc] initWithObjects:
|
||||
draftsFolderName,
|
||||
sieveFolderName,
|
||||
nil];
|
||||
else
|
||||
rootFolderNames = [[NSArray alloc] initWithObjects:
|
||||
draftsFolderName,
|
||||
nil];
|
||||
|
||||
rootFolderNames = [[NSArray alloc] initWithObjects:
|
||||
draftsFolderName,
|
||||
nil];
|
||||
|
||||
if (!fallbackIMAP4Server)
|
||||
{
|
||||
@@ -206,6 +204,147 @@ static NSString *fallbackIMAP4Server = nil;
|
||||
return [capability containsObject: @"quota"];
|
||||
}
|
||||
|
||||
- (BOOL) updateFilters
|
||||
{
|
||||
NSMutableString *header, *script;
|
||||
NGInternetSocketAddress *address;
|
||||
NSDictionary *result, *values;
|
||||
NSUserDefaults *ud;
|
||||
NGSieveClient *client;
|
||||
NSString *v;
|
||||
BOOL b;
|
||||
|
||||
if (![[NSUserDefaults standardUserDefaults] boolForKey: @"SOGoVacationEnabled"] &&
|
||||
![[NSUserDefaults standardUserDefaults] boolForKey: @"SOGoForwardEnabled"])
|
||||
return YES;
|
||||
|
||||
ud = [[context activeUser] userDefaults];
|
||||
b = NO;
|
||||
|
||||
header = [NSMutableString stringWithString: @"require ["];
|
||||
script = [NSMutableString string];
|
||||
|
||||
// Right now, we handle Sieve filters here and only for vacation
|
||||
// and forwards. Traditional filters support (for fileinto, for
|
||||
// example) will be added later.
|
||||
values = [ud objectForKey: @"Vacation"];
|
||||
|
||||
// We handle vacation messages.
|
||||
// See http://ietfreport.isoc.org/idref/draft-ietf-sieve-vacation/
|
||||
if (values && [[values objectForKey: @"enabled"] boolValue])
|
||||
{
|
||||
NSArray *addresses;
|
||||
NSString *text;
|
||||
BOOL ignore;
|
||||
int days, i;
|
||||
|
||||
days = [[values objectForKey: @"daysBetweenResponse"] intValue];
|
||||
addresses = [values objectForKey: @"autoReplyEmailAddresses"];
|
||||
ignore = [[values objectForKey: @"ignoreLists"] boolValue];
|
||||
text = [values objectForKey: @"autoReplyText"];
|
||||
b = YES;
|
||||
|
||||
if (days == 0)
|
||||
days = 7;
|
||||
|
||||
[header appendString: @"\"vacation\""];
|
||||
|
||||
// Skip mailing lists
|
||||
if (ignore)
|
||||
[script appendString: @"if allof ( not exists [\"list-help\", \"list-unsubscribe\", \"list-subscribe\", \"list-owner\", \"list-post\", \"list-archive\", \"list-id\", \"Mailing-List\"], not header :comparator \"i;ascii-casemap\" :is \"Precedence\" [\"list\", \"bulk\", \"junk\"], not header :comparator \"i;ascii-casemap\" :matches \"To\" \"Multiple recipients of*\" ) {"];
|
||||
|
||||
[script appendFormat: @"vacation :days %d :addresses [", days];
|
||||
|
||||
for (i = 0; i < [addresses count]; i++)
|
||||
{
|
||||
[script appendFormat: @"\"%@\"", [addresses objectAtIndex: i]];
|
||||
|
||||
if (i == [addresses count]-1)
|
||||
[script appendString: @"] "];
|
||||
else
|
||||
[script appendString: @", "];
|
||||
}
|
||||
|
||||
[script appendFormat: @"text:\r\n%@\r\n.\r\n;\r\n", text];
|
||||
|
||||
if (ignore)
|
||||
[script appendString: @"}\r\n"];
|
||||
}
|
||||
|
||||
|
||||
// We handle mail forward
|
||||
values = [ud objectForKey: @"Forward"];
|
||||
|
||||
if (values && [[values objectForKey: @"enabled"] boolValue])
|
||||
{
|
||||
b = YES;
|
||||
|
||||
v = [values objectForKey: @"forwardAddress"];
|
||||
|
||||
if (v && [v length] > 0)
|
||||
[script appendFormat: @"redirect \"%@\";\r\n", v];
|
||||
|
||||
if ([[values objectForKey: @"keepCopy"] boolValue])
|
||||
[script appendString: @"keep;\r\n"];
|
||||
}
|
||||
|
||||
if ([header compare: @"require ["] != NSOrderedSame)
|
||||
{
|
||||
[header appendString: @"];\r\n"];
|
||||
[script insertString: header atIndex: 0];
|
||||
}
|
||||
|
||||
// We connect to our Sieve server and upload the script
|
||||
address = [NGInternetSocketAddress addressWithPort: 2000
|
||||
onHost: [[self imap4URL] host]];
|
||||
|
||||
client = [NGSieveClient clientWithAddress: address];
|
||||
|
||||
if (!client) {
|
||||
[self errorWithFormat: @"Sieve connection failed on %@", [address description]];
|
||||
return NO;
|
||||
}
|
||||
|
||||
result = [client login: [[self imap4URL] user] password:[self imap4Password]];
|
||||
|
||||
if (![[result valueForKey:@"result"] boolValue]) {
|
||||
[self errorWithFormat: @"Could not login '%@' (%@) on Sieve server: %@: %@",
|
||||
[[self imap4URL] user], [self imap4Password], client, result];
|
||||
[client closeConnection];
|
||||
return NO;
|
||||
}
|
||||
|
||||
// We delete the existing Sieve script
|
||||
result = [client deleteScript: sieveScriptName];
|
||||
|
||||
if (![[result valueForKey:@"result"] boolValue]) {
|
||||
[self logWithFormat:@"WARNING: Could not delete Sieve script - continuing...: %@", result];
|
||||
}
|
||||
|
||||
// We put and activate the script only if we actually have a script
|
||||
// that does something...
|
||||
if (b)
|
||||
{
|
||||
result = [client putScript: sieveScriptName script: script];
|
||||
|
||||
if (![[result valueForKey:@"result"] boolValue]) {
|
||||
[self errorWithFormat:@"Could not upload Sieve script: %@", result];
|
||||
[client closeConnection];
|
||||
return NO;
|
||||
}
|
||||
|
||||
result = [client setActiveScript: sieveScriptName];
|
||||
if (![[result valueForKey:@"result"] boolValue]) {
|
||||
[self errorWithFormat:@"Could not enable Sieve script: %@", result];
|
||||
[client closeConnection];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
/* hierarchy */
|
||||
|
||||
- (SOGoMailAccount *) mailAccountFolder
|
||||
@@ -408,11 +547,6 @@ static NSString *fallbackIMAP4Server = nil;
|
||||
return folderName;
|
||||
}
|
||||
|
||||
// - (NSString *) sieveFolderNameInContext: (id) _ctx
|
||||
// {
|
||||
// return sieveFolderName;
|
||||
// }
|
||||
|
||||
- (NSString *) sentFolderNameInContext: (id)_ctx
|
||||
{
|
||||
NSString *folderName;
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
- (id) freeBusyObject: (NSString *) _key
|
||||
inContext: (WOContext *) _ctx;
|
||||
|
||||
- (id) mailAccountsFolder: (NSString *) _key
|
||||
inContext: (WOContext *) _ctx;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoUserFolder_H__ */
|
||||
|
||||
@@ -32,7 +32,10 @@
|
||||
|
||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSString+Utilities.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserFolder.h>
|
||||
#import <SoObjects/Mailer/SOGoMailAccount.h>
|
||||
#import "../../Main/SOGo.h"
|
||||
|
||||
#import "UIxPreferences.h"
|
||||
@@ -901,7 +904,21 @@ static BOOL forwardEnabled = NO;
|
||||
request = [context request];
|
||||
if ([[request method] isEqualToString: @"POST"])
|
||||
{
|
||||
SOGoMailAccount *account;
|
||||
id mailAccounts;
|
||||
id folder;
|
||||
|
||||
[userDefaults synchronize];
|
||||
|
||||
mailAccounts = [[[context activeUser] mailAccounts] objectAtIndex: 0];
|
||||
folder = [[self clientObject] mailAccountsFolder: @"Mail"
|
||||
inContext: context];
|
||||
account = [folder lookupName: [[mailAccounts objectForKey: @"name"] asCSSIdentifier]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
|
||||
[account updateFilters];
|
||||
|
||||
if (composeMessageTypeHasChanged)
|
||||
// Due to a limitation of CKEDITOR, we reload the page when the user
|
||||
// changes the composition mode to avoid Javascript errors.
|
||||
|
||||
Reference in New Issue
Block a user