diff --git a/SoObjects/Mailer/SOGoMailAccount.h b/SoObjects/Mailer/SOGoMailAccount.h index 2b6c871a3..66da6f06d 100644 --- a/SoObjects/Mailer/SOGoMailAccount.h +++ b/SoObjects/Mailer/SOGoMailAccount.h @@ -80,8 +80,10 @@ typedef enum { - (id) getInboxQuota; - (BOOL) updateFilters; +- (BOOL) updateFiltersAndForceActivation: (BOOL) forceActivation; - (BOOL) updateFiltersWithUsername: (NSString *) theUsername - andPassword: (NSString *) thePassword; + andPassword: (NSString *) thePassword + forceActivation: (BOOL) forceActivation; - (NSArray *) identities; - (NSString *) signature; diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index f1980e37c..e58539a13 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -300,19 +300,32 @@ static NSString *inboxFolderName = @"INBOX"; return inboxQuota; } +- (BOOL) updateFiltersAndForceActivation: (BOOL) forceActivation +{ + return [self updateFiltersWithUsername: nil + andPassword: nil + forceActivation: forceActivation]; +} + - (BOOL) updateFilters { - return [self updateFiltersWithUsername: nil andPassword: nil]; + return [self updateFiltersWithUsername: nil + andPassword: nil + forceActivation: NO]; } - (BOOL) updateFiltersWithUsername: (NSString *) theUsername andPassword: (NSString *) thePassword + forceActivation: (BOOL) forceActivation { SOGoSieveManager *manager; manager = [SOGoSieveManager sieveManagerForUser: [context activeUser]]; - return [manager updateFiltersForAccount: self withUsername: theUsername andPassword: thePassword]; + return [manager updateFiltersForAccount: self + withUsername: theUsername + andPassword: thePassword + forceActivation: forceActivation]; } diff --git a/SoObjects/SOGo/SOGoSieveManager.h b/SoObjects/SOGo/SOGoSieveManager.h index 05b9a8fe7..0a179dc65 100644 --- a/SoObjects/SOGo/SOGoSieveManager.h +++ b/SoObjects/SOGo/SOGoSieveManager.h @@ -50,10 +50,13 @@ withUsername: (NSString *) theUsername andPassword: (NSString *) thePassword; +- (BOOL) hasActiveExternalSieveScripts: (NGSieveClient *) client; + - (BOOL) updateFiltersForAccount: (SOGoMailAccount *) theAccount; - (BOOL) updateFiltersForAccount: (SOGoMailAccount *) theAccount withUsername: (NSString *) theUsername - andPassword: (NSString *) thePassword; + andPassword: (NSString *) thePassword + forceActivation: (BOOL) forceActivation; @end diff --git a/SoObjects/SOGo/SOGoSieveManager.m b/SoObjects/SOGo/SOGoSieveManager.m index a002f8d70..bbc6366af 100644 --- a/SoObjects/SOGo/SOGoSieveManager.m +++ b/SoObjects/SOGo/SOGoSieveManager.m @@ -804,6 +804,24 @@ static NSString *sieveScriptName = @"sogo"; return [client autorelease]; } +- (BOOL) hasActiveExternalSieveScripts: (NGSieveClient *) client +{ + NSDictionary *scripts; + NSEnumerator *keys; + NSString *key; + + scripts = [client listScripts]; + + keys = [scripts keyEnumerator]; + while ((key = [keys nextObject])) + { + if ([key caseInsensitiveCompare: @"sogo"] != NSOrderedSame && + [[[scripts objectForKey: key] stringValue] length] > 0) + return YES; + } + + return NO; +} // // @@ -812,7 +830,8 @@ static NSString *sieveScriptName = @"sogo"; { return [self updateFiltersForAccount: theAccount withUsername: nil - andPassword: nil]; + andPassword: nil + forceActivation: NO]; } // @@ -821,6 +840,7 @@ static NSString *sieveScriptName = @"sogo"; - (BOOL) updateFiltersForAccount: (SOGoMailAccount *) theAccount withUsername: (NSString *) theUsername andPassword: (NSString *) thePassword + forceActivation: (BOOL) forceActivation { NSString *filterScript, *v, *content; NSMutableArray *req; @@ -830,7 +850,7 @@ static NSString *sieveScriptName = @"sogo"; SOGoDomainDefaults *dd; NGSieveClient *client; NGImap4Client *imapClient; - BOOL b, dateCapability; + BOOL b, activate, dateCapability; unsigned int now; dd = [user domainDefaults]; @@ -844,6 +864,9 @@ static NSString *sieveScriptName = @"sogo"; if (!client) return NO; + // Activate script Sieve when forced or when no external script is enabled + activate = forceActivation || ![self hasActiveExternalSieveScripts: client]; + // We adjust the "methodRequirements" based on the server's // capabilities. Cyrus exposes "imapflags" while Dovecot (and // potentially others) expose "imap4flags" as specified in RFC5332 @@ -1094,6 +1117,7 @@ static NSString *sieveScriptName = @"sogo"; intoArray: req]; [script appendString: @"\n"]; [script appendString: v]; + b = YES; } } @@ -1102,21 +1126,23 @@ static NSString *sieveScriptName = @"sogo"; header = [NSString stringWithFormat: @"require [\"%@\"];\r\n", [[req uniqueObjects] componentsJoinedByString: @"\",\""]]; [script insertString: header atIndex: 0]; - b = YES; } /* We ensure to deactive the current active script since it could prevent its deletion from the server. */ + if (activate) + result = [client setActiveScript: @""]; + // 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 && [script length]) { - result = [client setActiveScript: @""]; - // 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]; - result = [client putScript: sieveScriptName script: script]; if (![[result valueForKey:@"result"] boolValue]) @@ -1126,12 +1152,15 @@ static NSString *sieveScriptName = @"sogo"; return NO; } - result = [client setActiveScript: sieveScriptName]; - if (![[result valueForKey:@"result"] boolValue]) + if (activate) { - [self logWithFormat: @"Could not enable Sieve script: %@", result]; - [client closeConnection]; - return NO; + result = [client setActiveScript: sieveScriptName]; + if (![[result valueForKey:@"result"] boolValue]) + { + [self logWithFormat: @"Could not enable Sieve script: %@", result]; + [client closeConnection]; + return NO; + } } } diff --git a/UI/PreferencesUI/UIxJSONPreferences.m b/UI/PreferencesUI/UIxJSONPreferences.m index 337c2106e..cc157e594 100644 --- a/UI/PreferencesUI/UIxJSONPreferences.m +++ b/UI/PreferencesUI/UIxJSONPreferences.m @@ -25,18 +25,23 @@ #import #import +#import #import #import #import #import +#import #import #import +#import #import #import #import #import +#import +#import #import #import "UIxJSONPreferences.h" @@ -71,6 +76,27 @@ static SoProduct *preferencesProduct = nil; return labelsDictionary; } +// +// Used internally +// +- (BOOL) _hasActiveExternalSieveScripts +{ + NGSieveClient *client; + SOGoMailAccount *account; + SOGoMailAccounts *folder; + SOGoSieveManager *manager; + + folder = [[[context activeUser] homeFolderInContext: context] mailAccountsFolder: @"Mail" inContext: context]; + account = [folder lookupName: @"0" inContext: context acquire: NO]; + manager = [SOGoSieveManager sieveManagerForUser: [context activeUser]]; + client = [manager clientForAccount: account]; + + if (client) + return [manager hasActiveExternalSieveScripts: client]; + + return NO; +} + - (WOResponse *) jsonDefaultsAction { return [self responseWithStatus: 200 @@ -401,6 +427,9 @@ static SoProduct *preferencesProduct = nil; [values setObject: vacation forKey: @"Vacation"]; } + // Detect if an external Sieve script is active + [values setObject: [NSNumber numberWithBool: [self _hasActiveExternalSieveScripts]] forKey: @"hasActiveExternalSieveScripts"]; + return [values jsonRepresentation]; } diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index b2e4f38b2..615e9f734 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -728,25 +728,6 @@ static NSArray *reminderValues = nil; return [[user domainDefaults] sieveScriptsEnabled]; } -- (NSString *) hasActiveExternalSieveScripts -{ - NSDictionary *scripts; - NSEnumerator *keys; - NSString *key; - - scripts = [[self _sieveClient] listScripts]; - - keys = [scripts keyEnumerator]; - while ((key = [keys nextObject])) - { - if ([key caseInsensitiveCompare: @"sogo"] != NSOrderedSame && - [[scripts objectForKey: key] boolValue]) - return @"true"; - } - - return @"false"; -} - // // Used by wox template // @@ -1645,12 +1626,13 @@ static NSArray *reminderValues = nil; // We check if the Sieve server is available *ONLY* if at least one of the option is enabled if (!([dd sieveScriptsEnabled] || [dd vacationEnabled] || [dd forwardEnabled]) || [self _isSieveServerAvailable]) { + BOOL forceActivation = ![[v objectForKey: @"hasActiveExternalSieveScripts"] boolValue]; folder = [[[context activeUser] homeFolderInContext: context] mailAccountsFolder: @"Mail" inContext: context]; account = [folder lookupName: @"0" inContext: context acquire: NO]; - if (![account updateFilters]) + if (![account updateFiltersAndForceActivation: forceActivation]) { results = (id ) [self responseWithStatus: 502 andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Connection error", @"message", nil]]; diff --git a/UI/Templates/PreferencesUI/UIxPreferences.wox b/UI/Templates/PreferencesUI/UIxPreferences.wox index 127a007b9..0ffe6a875 100644 --- a/UI/Templates/PreferencesUI/UIxPreferences.wox +++ b/UI/Templates/PreferencesUI/UIxPreferences.wox @@ -23,7 +23,6 @@ var forwardConstraints = ; var forwardConstraintsDomains = ; var sieveCapabilities = ; - var hasActiveExternalSieveScripts = ; + + diff --git a/UI/WebServerResources/js/Preferences/PreferencesController.js b/UI/WebServerResources/js/Preferences/PreferencesController.js index c964c2616..d23aedc28 100644 --- a/UI/WebServerResources/js/Preferences/PreferencesController.js +++ b/UI/WebServerResources/js/Preferences/PreferencesController.js @@ -18,7 +18,6 @@ this.timeZonesSearchText = ''; this.sieveVariablesCapability = ($window.sieveCapabilities.indexOf('variables') >= 0); this.mailLabelKeyRE = new RegExp(/^(?!^_\$)[^(){} %*\"\\\\]*?$/); - this.hasActiveExternalSieveScripts = $window.hasActiveExternalSieveScripts; // Set alternate avatar in User service if (Preferences.defaults.SOGoAlternateAvatar) @@ -285,6 +284,11 @@ }); }; + this.manageSieveScript = function(form) { + this.preferences.defaults.hasActiveExternalSieveScripts = false; + form.$setDirty(); + }; + this.confirmChanges = function($event, form) { var target;