diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index ca602a3a9a..2a6ec3db18 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -1973,6 +1973,16 @@ SOGo webmail interface. The parameter is an array, for example: `SOGoMailListViewColumnsOrder = (Flagged, Attachment, Priority, From, Subject, Unread, Date, Size);` +|D |SOGoExternalAvatarsEnabled +|Parameter used to enable fetching of avatars from remote services. + +Defaults to `YES` when unset. + +|U |SOGoGravatarEnabled +|Parameter used to activate fetching of avatars from http://gravatar.com/[Gravatar]. + +Defaults to `YES` when unset. + |D |SOGoVacationEnabled |Parameter used to activate the edition from the preferences window of a vacation message. diff --git a/NEWS b/NEWS index 2c06ee4191..3829d04542 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Enhancements - [web] expose all email addresses in autocompletion of message editor (#3443) + - [web] Gravatar service can now be disabled (#3600) Bug fixes - [web] fixed creation of chip on blur (sgTransformOnBlur directive) diff --git a/SoObjects/SOGo/SOGoDefaults.plist b/SoObjects/SOGo/SOGoDefaults.plist index d26d32e182..f2a83a1518 100644 --- a/SoObjects/SOGo/SOGoDefaults.plist +++ b/SoObjects/SOGo/SOGoDefaults.plist @@ -54,12 +54,14 @@ SOGoFirstWeekOfYear = "January1"; SOGoShortDateFormat = "%d-%b-%y"; SOGoLongDateFormat = "%A, %B %d, %Y"; + SOGoExternalAvatarsEnabled = YES; + SOGoGravatarEnabled = NO; + SOGoAlternateAvatar = "none"; SOGoIMAPServer = "localhost"; SOGoMailDomain = "localhost"; SOGoSelectedAddressBook = "collected"; SOGoRefreshViewCheck = "manually"; - SOGoAlternateAvatar = "none"; SOGoMailMessageForwarding = "inline"; SOGoMailReplyPlacement = "below"; SOGoMailSignaturePlacement = "below"; diff --git a/SoObjects/SOGo/SOGoDomainDefaults.h b/SoObjects/SOGo/SOGoDomainDefaults.h index b8cc6f30bc..d603d8eac2 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.h +++ b/SoObjects/SOGo/SOGoDomainDefaults.h @@ -47,6 +47,7 @@ - (NSString *) imapFolderSeparator; - (BOOL) imapAclConformsToIMAPExt; - (BOOL) forceExternalLoginWithEmail; +- (BOOL) externalAvatarsEnabled; - (BOOL) sieveScriptsEnabled; - (BOOL) forwardEnabled; - (int) forwardConstraints; diff --git a/SoObjects/SOGo/SOGoDomainDefaults.m b/SoObjects/SOGo/SOGoDomainDefaults.m index 72893fedad..55fc9cd248 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.m +++ b/SoObjects/SOGo/SOGoDomainDefaults.m @@ -1,6 +1,6 @@ /* SOGoDomainDefaults.m - this file is part of SOGo * - * Copyright (C) 2009-2015 Inverse inc. + * Copyright (C) 2009-2016 Inverse inc. * * 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 @@ -191,6 +191,11 @@ - (BOOL) forceExternalLoginWithEmail return [self boolForKey: @"SOGoForceIMAPLoginWithEmail"]; } +- (BOOL) externalAvatarsEnabled +{ + return [self boolForKey: @"SOGoExternalAvatarsEnabled"]; +} + - (BOOL) sieveScriptsEnabled { return [self boolForKey: @"SOGoSieveScriptsEnabled"]; diff --git a/SoObjects/SOGo/SOGoUserDefaults.h b/SoObjects/SOGo/SOGoUserDefaults.h index fcf97c7b20..828fbaf89e 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.h +++ b/SoObjects/SOGo/SOGoUserDefaults.h @@ -126,6 +126,7 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (void) setRefreshViewCheck: (NSString *) newValue; - (NSString *) refreshViewCheck; +- (BOOL) gravatarEnabled; - (void) setAlternateAvatar: (NSString *) newValue; - (NSString *) alternateAvatar; diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index 910fad1027..e895f2cf73 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -514,6 +514,11 @@ - (NSString *) refreshViewCheck return [self stringForKey: @"SOGoRefreshViewCheck"]; } +- (BOOL) gravatarEnabled +{ + return [self boolForKey: @"SOGoGravatarEnabled"]; +} + - (void) setAlternateAvatar: (NSString *) newValue { [self setObject: newValue forKey: @"SOGoAlternateAvatar"]; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index 5b3174fae8..b073da2e0f 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -365,6 +365,7 @@ "TLS" = "TLS"; /* Avatars */ +"Use Gravatar" = "Use Gravatar"; "Alternate Avatar" = "Alternate Avatar"; "none" = "None"; "identicon" = "Ident Icon"; diff --git a/UI/PreferencesUI/UIxJSONPreferences.m b/UI/PreferencesUI/UIxJSONPreferences.m index 7ea1b4fe26..3548ea5871 100644 --- a/UI/PreferencesUI/UIxJSONPreferences.m +++ b/UI/PreferencesUI/UIxJSONPreferences.m @@ -30,6 +30,7 @@ #import #import +#import #import #import #import @@ -73,6 +74,7 @@ - (WOResponse *) jsonDefaultsAction { NSMutableDictionary *values, *account; SOGoUserDefaults *defaults; + SOGoDomainDefaults *domainDefaults; NSMutableArray *accounts; NSDictionary *categoryLabels; NSDictionary *locale; @@ -84,6 +86,7 @@ - (WOResponse *) jsonDefaultsAction } defaults = [[context activeUser] userDefaults]; + domainDefaults = [[context activeUser] domainDefaults]; categoryLabels = nil; // @@ -110,8 +113,18 @@ - (WOResponse *) jsonDefaultsAction if (![[defaults source] objectForKey: @"SOGoRefreshViewCheck"]) [[defaults source] setObject: [defaults refreshViewCheck] forKey: @"SOGoRefreshViewCheck"]; - if (![[defaults source] objectForKey: @"SOGoAlternateAvatar"]) - [[defaults source] setObject: [defaults alternateAvatar] forKey: @"SOGoAlternateAvatar"]; + if ([domainDefaults externalAvatarsEnabled]) + { + if (![[defaults source] objectForKey: @"SOGoGravatarEnabled"]) + [[defaults source] setObject: [NSNumber numberWithBool: [defaults gravatarEnabled]] forKey: @"SOGoGravatarEnabled"]; + if (![[defaults source] objectForKey: @"SOGoAlternateAvatar"]) + [[defaults source] setObject: [defaults alternateAvatar] forKey: @"SOGoAlternateAvatar"]; + } + else + { + [[defaults source] setObject: [NSNumber numberWithInt: 0] forKey: @"SOGoGravatarEnabled"]; + [[defaults source] removeObjectForKey: @"SOGoAlternateAvatar"]; + } // // Default Calendar preferences diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 7b0c97f846..b9c24eed57 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -686,7 +686,7 @@ - (NSArray *) hoursList // SOGoUserSettings *us; // NSMutableDictionary *moduleSettings; // NSArray *whiteList; - + // us = [user userSettings]; // moduleSettings = [us objectForKey: @"Calendar"]; // whiteList = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"]; @@ -697,7 +697,7 @@ - (NSArray *) hoursList // { // SOGoUserSettings *us; // NSMutableDictionary *moduleSettings; - + // us = [user userSettings]; // moduleSettings = [us objectForKey: @"Calendar"]; // [moduleSettings setObject: whiteListString forKey: @"PreventInvitationsWhitelist"]; @@ -890,7 +890,7 @@ - (NSArray *) refreshViewList value = @"every_minute"; else if (interval == 60) value = @"once_per_hour"; - else if (interval == 2 || interval == 5 || interval == 10 + else if (interval == 2 || interval == 5 || interval == 10 || interval == 20 || interval == 30) value = [NSString stringWithFormat: @"every_%d_minutes", interval]; else @@ -1417,6 +1417,11 @@ - (NSString *) itemModuleText return [self labelForKey: item]; } +- (BOOL) externalAvatarsEnabled +{ + return [[user domainDefaults] externalAvatarsEnabled]; +} + - (NSArray *) alternateAvatar { // See: https://en.gravatar.com/site/implement/images/ @@ -1795,7 +1800,7 @@ - (BOOL) mailAuxiliaryUserAccountsEnabled // - (void) _extractMainIdentity: (NSDictionary *) identity inDictionary: (NSMutableDictionary *) target - + { /* We perform some validation here as we have no guaranty on the input validity. */ @@ -1825,7 +1830,7 @@ - (void) _extractMainIdentity: (NSDictionary *) identity [target setObject: value forKey: @"SOGoMailCustomEmail"]; else [target removeObjectForKey: @"SOGoMailCustomEmail"]; - + value = [[identity objectForKey: @"fullName"] stringByTrimmingSpaces]; if ([value length] == 0 @@ -1878,11 +1883,11 @@ - (void) _extractMainReceiptsPreferences: (NSDictionary *) receipts action = [receipts objectForKey: @"receiptNonRecipientAction"]; if ([self _validateReceiptAction: action]) [target setObject: action forKey: @"SOGoMailReceiptNonRecipientAction"]; - + action = [receipts objectForKey: @"receiptOutsideDomainAction"]; if ([self _validateReceiptAction: action]) [target setObject: action forKey: @"SOGoMailReceiptOutsideDomainAction"]; - + action = [receipts objectForKey: @"receiptAnyAction"]; if ([self _validateReceiptAction: action]) [target setObject: action forKey: @"SOGoMailReceiptAnyAction"]; @@ -2128,10 +2133,10 @@ - (NSString *) forwardEnabled { id results; id o, v; - + o = [[[context request] contentAsString] objectFromJSONString]; results = nil; - + // Proceed with data sanitization of the "defaults" if ((v = [o objectForKey: @"defaults"])) { @@ -2156,7 +2161,15 @@ - (NSString *) forwardEnabled if ([[v objectForKey: @"SOGoLongDateFormat"] isEqualToString: @"default"]) [v removeObjectForKey: @"SOGoLongDateFormat"]; - + + if (![self externalAvatarsEnabled]) + { + [v removeObjectForKey: @"SOGoGravatarEnabled"]; + [[[user userDefaults] source] removeObjectForKey: @"SOGoGravatarEnabled"]; + [v removeObjectForKey: @"SOGoAlternateAvatar"]; + [[[user userDefaults] source] removeObjectForKey: @"SOGoAlternateAvatar"]; + } + // // We sanitize mail labels // @@ -2166,20 +2179,20 @@ - (NSString *) forwardEnabled // We encode correctly our keys sanitizedLabels = [NSMutableDictionary dictionary]; allKeys = [newLabels allKeys]; - + for (i = 0; i < [allKeys count]; i++) { name = [allKeys objectAtIndex: i]; - + if (![name is7bitSafe]) name = [name stringByEncodingImap4FolderName]; - + name = [name lowercaseString]; - + [sanitizedLabels setObject: [newLabels objectForKey: [allKeys objectAtIndex: i]] forKey: name]; } - + [v setObject: sanitizedLabels forKey: @"SOGoMailLabelsColors"]; } @@ -2202,23 +2215,23 @@ - (NSString *) forwardEnabled } [[[user userDefaults] source] setValues: v]; - + if ([[user userDefaults] synchronize]) { SOGoMailAccount *account; SOGoMailAccounts *folder; SOGoDomainDefaults *dd; - + dd = [[context activeUser] domainDefaults]; // 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]) { - + folder = [[[context activeUser] homeFolderInContext: context] mailAccountsFolder: @"Mail" inContext: context]; account = [folder lookupName: @"0" inContext: context acquire: NO]; - + if (![account updateFilters]) { results = (id ) [self responseWithStatus: 502 @@ -2230,7 +2243,7 @@ - (NSString *) forwardEnabled andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"message", nil]]; } } - + if ((v = [o objectForKey: @"settings"])) { [[[user userSettings] source] setValues: v]; diff --git a/UI/Templates/PreferencesUI/UIxPreferences.wox b/UI/Templates/PreferencesUI/UIxPreferences.wox index ff5517e8a3..8364b4630d 100644 --- a/UI/Templates/PreferencesUI/UIxPreferences.wox +++ b/UI/Templates/PreferencesUI/UIxPreferences.wox @@ -194,16 +194,28 @@ - - - - - - - - - - + +
+ + + + + + + + + + + + + +
+
diff --git a/UI/WebServerResources/js/Common/sgAvatarImage.directive.js b/UI/WebServerResources/js/Common/sgAvatarImage.directive.js index 6f3ba1e615..1c568b2326 100644 --- a/UI/WebServerResources/js/Common/sgAvatarImage.directive.js +++ b/UI/WebServerResources/js/Common/sgAvatarImage.directive.js @@ -60,7 +60,8 @@ if (email && vm.urlEmail != email) { // Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat) showGenericAvatar(); - getGravatar(email); + if (Preferences.defaults.SOGoGravatarEnabled) + getGravatar(email); } else if (!email) showGenericAvatar();