Allow disabling Gravatar

Resolves #3600
pull/210/head
Francis Lachapelle 2016-05-25 16:04:58 -04:00
parent 9fc22f2689
commit a9ee261eff
12 changed files with 100 additions and 35 deletions

View File

@ -1973,6 +1973,16 @@ SOGo webmail interface. The parameter is an array, for example:
`SOGoMailListViewColumnsOrder = (Flagged, Attachment, Priority, From, Subject, Unread, Date, Size);` `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 |D |SOGoVacationEnabled
|Parameter used to activate the edition from the preferences window of a |Parameter used to activate the edition from the preferences window of a
vacation message. vacation message.

1
NEWS
View File

@ -3,6 +3,7 @@
Enhancements Enhancements
- [web] expose all email addresses in autocompletion of message editor (#3443) - [web] expose all email addresses in autocompletion of message editor (#3443)
- [web] Gravatar service can now be disabled (#3600)
Bug fixes Bug fixes
- [web] fixed creation of chip on blur (sgTransformOnBlur directive) - [web] fixed creation of chip on blur (sgTransformOnBlur directive)

View File

@ -54,12 +54,14 @@
SOGoFirstWeekOfYear = "January1"; SOGoFirstWeekOfYear = "January1";
SOGoShortDateFormat = "%d-%b-%y"; SOGoShortDateFormat = "%d-%b-%y";
SOGoLongDateFormat = "%A, %B %d, %Y"; SOGoLongDateFormat = "%A, %B %d, %Y";
SOGoExternalAvatarsEnabled = YES;
SOGoGravatarEnabled = NO;
SOGoAlternateAvatar = "none";
SOGoIMAPServer = "localhost"; SOGoIMAPServer = "localhost";
SOGoMailDomain = "localhost"; SOGoMailDomain = "localhost";
SOGoSelectedAddressBook = "collected"; SOGoSelectedAddressBook = "collected";
SOGoRefreshViewCheck = "manually"; SOGoRefreshViewCheck = "manually";
SOGoAlternateAvatar = "none";
SOGoMailMessageForwarding = "inline"; SOGoMailMessageForwarding = "inline";
SOGoMailReplyPlacement = "below"; SOGoMailReplyPlacement = "below";
SOGoMailSignaturePlacement = "below"; SOGoMailSignaturePlacement = "below";

View File

@ -47,6 +47,7 @@
- (NSString *) imapFolderSeparator; - (NSString *) imapFolderSeparator;
- (BOOL) imapAclConformsToIMAPExt; - (BOOL) imapAclConformsToIMAPExt;
- (BOOL) forceExternalLoginWithEmail; - (BOOL) forceExternalLoginWithEmail;
- (BOOL) externalAvatarsEnabled;
- (BOOL) sieveScriptsEnabled; - (BOOL) sieveScriptsEnabled;
- (BOOL) forwardEnabled; - (BOOL) forwardEnabled;
- (int) forwardConstraints; - (int) forwardConstraints;

View File

@ -1,6 +1,6 @@
/* SOGoDomainDefaults.m - this file is part of SOGo /* 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 * 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 * it under the terms of the GNU General Public License as published by
@ -191,6 +191,11 @@
return [self boolForKey: @"SOGoForceIMAPLoginWithEmail"]; return [self boolForKey: @"SOGoForceIMAPLoginWithEmail"];
} }
- (BOOL) externalAvatarsEnabled
{
return [self boolForKey: @"SOGoExternalAvatarsEnabled"];
}
- (BOOL) sieveScriptsEnabled - (BOOL) sieveScriptsEnabled
{ {
return [self boolForKey: @"SOGoSieveScriptsEnabled"]; return [self boolForKey: @"SOGoSieveScriptsEnabled"];

View File

@ -126,6 +126,7 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (void) setRefreshViewCheck: (NSString *) newValue; - (void) setRefreshViewCheck: (NSString *) newValue;
- (NSString *) refreshViewCheck; - (NSString *) refreshViewCheck;
- (BOOL) gravatarEnabled;
- (void) setAlternateAvatar: (NSString *) newValue; - (void) setAlternateAvatar: (NSString *) newValue;
- (NSString *) alternateAvatar; - (NSString *) alternateAvatar;

View File

@ -514,6 +514,11 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
return [self stringForKey: @"SOGoRefreshViewCheck"]; return [self stringForKey: @"SOGoRefreshViewCheck"];
} }
- (BOOL) gravatarEnabled
{
return [self boolForKey: @"SOGoGravatarEnabled"];
}
- (void) setAlternateAvatar: (NSString *) newValue - (void) setAlternateAvatar: (NSString *) newValue
{ {
[self setObject: newValue forKey: @"SOGoAlternateAvatar"]; [self setObject: newValue forKey: @"SOGoAlternateAvatar"];

View File

@ -365,6 +365,7 @@
"TLS" = "TLS"; "TLS" = "TLS";
/* Avatars */ /* Avatars */
"Use Gravatar" = "Use Gravatar";
"Alternate Avatar" = "Alternate Avatar"; "Alternate Avatar" = "Alternate Avatar";
"none" = "None"; "none" = "None";
"identicon" = "Ident Icon"; "identicon" = "Ident Icon";

View File

@ -30,6 +30,7 @@
#import <SOGo/NSObject+Utilities.h> #import <SOGo/NSObject+Utilities.h>
#import <SOGo/NSString+Utilities.h> #import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h> #import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserSettings.h> #import <SOGo/SOGoUserSettings.h>
@ -73,6 +74,7 @@ static SoProduct *preferencesProduct = nil;
{ {
NSMutableDictionary *values, *account; NSMutableDictionary *values, *account;
SOGoUserDefaults *defaults; SOGoUserDefaults *defaults;
SOGoDomainDefaults *domainDefaults;
NSMutableArray *accounts; NSMutableArray *accounts;
NSDictionary *categoryLabels; NSDictionary *categoryLabels;
NSDictionary *locale; NSDictionary *locale;
@ -84,6 +86,7 @@ static SoProduct *preferencesProduct = nil;
} }
defaults = [[context activeUser] userDefaults]; defaults = [[context activeUser] userDefaults];
domainDefaults = [[context activeUser] domainDefaults];
categoryLabels = nil; categoryLabels = nil;
// //
@ -110,8 +113,18 @@ static SoProduct *preferencesProduct = nil;
if (![[defaults source] objectForKey: @"SOGoRefreshViewCheck"]) if (![[defaults source] objectForKey: @"SOGoRefreshViewCheck"])
[[defaults source] setObject: [defaults refreshViewCheck] forKey: @"SOGoRefreshViewCheck"]; [[defaults source] setObject: [defaults refreshViewCheck] forKey: @"SOGoRefreshViewCheck"];
if (![[defaults source] objectForKey: @"SOGoAlternateAvatar"]) if ([domainDefaults externalAvatarsEnabled])
[[defaults source] setObject: [defaults alternateAvatar] forKey: @"SOGoAlternateAvatar"]; {
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 // Default Calendar preferences

View File

@ -686,7 +686,7 @@ static NSArray *reminderValues = nil;
// SOGoUserSettings *us; // SOGoUserSettings *us;
// NSMutableDictionary *moduleSettings; // NSMutableDictionary *moduleSettings;
// NSArray *whiteList; // NSArray *whiteList;
// us = [user userSettings]; // us = [user userSettings];
// moduleSettings = [us objectForKey: @"Calendar"]; // moduleSettings = [us objectForKey: @"Calendar"];
// whiteList = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"]; // whiteList = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"];
@ -697,7 +697,7 @@ static NSArray *reminderValues = nil;
// { // {
// SOGoUserSettings *us; // SOGoUserSettings *us;
// NSMutableDictionary *moduleSettings; // NSMutableDictionary *moduleSettings;
// us = [user userSettings]; // us = [user userSettings];
// moduleSettings = [us objectForKey: @"Calendar"]; // moduleSettings = [us objectForKey: @"Calendar"];
// [moduleSettings setObject: whiteListString forKey: @"PreventInvitationsWhitelist"]; // [moduleSettings setObject: whiteListString forKey: @"PreventInvitationsWhitelist"];
@ -890,7 +890,7 @@ static NSArray *reminderValues = nil;
value = @"every_minute"; value = @"every_minute";
else if (interval == 60) else if (interval == 60)
value = @"once_per_hour"; value = @"once_per_hour";
else if (interval == 2 || interval == 5 || interval == 10 else if (interval == 2 || interval == 5 || interval == 10
|| interval == 20 || interval == 30) || interval == 20 || interval == 30)
value = [NSString stringWithFormat: @"every_%d_minutes", interval]; value = [NSString stringWithFormat: @"every_%d_minutes", interval];
else else
@ -1417,6 +1417,11 @@ static NSArray *reminderValues = nil;
return [self labelForKey: item]; return [self labelForKey: item];
} }
- (BOOL) externalAvatarsEnabled
{
return [[user domainDefaults] externalAvatarsEnabled];
}
- (NSArray *) alternateAvatar - (NSArray *) alternateAvatar
{ {
// See: https://en.gravatar.com/site/implement/images/ // See: https://en.gravatar.com/site/implement/images/
@ -1795,7 +1800,7 @@ static NSArray *reminderValues = nil;
// //
- (void) _extractMainIdentity: (NSDictionary *) identity - (void) _extractMainIdentity: (NSDictionary *) identity
inDictionary: (NSMutableDictionary *) target inDictionary: (NSMutableDictionary *) target
{ {
/* We perform some validation here as we have no guaranty on the input /* We perform some validation here as we have no guaranty on the input
validity. */ validity. */
@ -1825,7 +1830,7 @@ static NSArray *reminderValues = nil;
[target setObject: value forKey: @"SOGoMailCustomEmail"]; [target setObject: value forKey: @"SOGoMailCustomEmail"];
else else
[target removeObjectForKey: @"SOGoMailCustomEmail"]; [target removeObjectForKey: @"SOGoMailCustomEmail"];
value = [[identity objectForKey: @"fullName"] value = [[identity objectForKey: @"fullName"]
stringByTrimmingSpaces]; stringByTrimmingSpaces];
if ([value length] == 0 if ([value length] == 0
@ -1878,11 +1883,11 @@ static NSArray *reminderValues = nil;
action = [receipts objectForKey: @"receiptNonRecipientAction"]; action = [receipts objectForKey: @"receiptNonRecipientAction"];
if ([self _validateReceiptAction: action]) if ([self _validateReceiptAction: action])
[target setObject: action forKey: @"SOGoMailReceiptNonRecipientAction"]; [target setObject: action forKey: @"SOGoMailReceiptNonRecipientAction"];
action = [receipts objectForKey: @"receiptOutsideDomainAction"]; action = [receipts objectForKey: @"receiptOutsideDomainAction"];
if ([self _validateReceiptAction: action]) if ([self _validateReceiptAction: action])
[target setObject: action forKey: @"SOGoMailReceiptOutsideDomainAction"]; [target setObject: action forKey: @"SOGoMailReceiptOutsideDomainAction"];
action = [receipts objectForKey: @"receiptAnyAction"]; action = [receipts objectForKey: @"receiptAnyAction"];
if ([self _validateReceiptAction: action]) if ([self _validateReceiptAction: action])
[target setObject: action forKey: @"SOGoMailReceiptAnyAction"]; [target setObject: action forKey: @"SOGoMailReceiptAnyAction"];
@ -2128,10 +2133,10 @@ static NSArray *reminderValues = nil;
{ {
id <WOActionResults> results; id <WOActionResults> results;
id o, v; id o, v;
o = [[[context request] contentAsString] objectFromJSONString]; o = [[[context request] contentAsString] objectFromJSONString];
results = nil; results = nil;
// Proceed with data sanitization of the "defaults" // Proceed with data sanitization of the "defaults"
if ((v = [o objectForKey: @"defaults"])) if ((v = [o objectForKey: @"defaults"]))
{ {
@ -2156,7 +2161,15 @@ static NSArray *reminderValues = nil;
if ([[v objectForKey: @"SOGoLongDateFormat"] isEqualToString: @"default"]) if ([[v objectForKey: @"SOGoLongDateFormat"] isEqualToString: @"default"])
[v removeObjectForKey: @"SOGoLongDateFormat"]; [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 // We sanitize mail labels
// //
@ -2166,20 +2179,20 @@ static NSArray *reminderValues = nil;
// We encode correctly our keys // We encode correctly our keys
sanitizedLabels = [NSMutableDictionary dictionary]; sanitizedLabels = [NSMutableDictionary dictionary];
allKeys = [newLabels allKeys]; allKeys = [newLabels allKeys];
for (i = 0; i < [allKeys count]; i++) for (i = 0; i < [allKeys count]; i++)
{ {
name = [allKeys objectAtIndex: i]; name = [allKeys objectAtIndex: i];
if (![name is7bitSafe]) if (![name is7bitSafe])
name = [name stringByEncodingImap4FolderName]; name = [name stringByEncodingImap4FolderName];
name = [name lowercaseString]; name = [name lowercaseString];
[sanitizedLabels setObject: [newLabels objectForKey: [allKeys objectAtIndex: i]] [sanitizedLabels setObject: [newLabels objectForKey: [allKeys objectAtIndex: i]]
forKey: name]; forKey: name];
} }
[v setObject: sanitizedLabels forKey: @"SOGoMailLabelsColors"]; [v setObject: sanitizedLabels forKey: @"SOGoMailLabelsColors"];
} }
@ -2202,23 +2215,23 @@ static NSArray *reminderValues = nil;
} }
[[[user userDefaults] source] setValues: v]; [[[user userDefaults] source] setValues: v];
if ([[user userDefaults] synchronize]) if ([[user userDefaults] synchronize])
{ {
SOGoMailAccount *account; SOGoMailAccount *account;
SOGoMailAccounts *folder; SOGoMailAccounts *folder;
SOGoDomainDefaults *dd; SOGoDomainDefaults *dd;
dd = [[context activeUser] domainDefaults]; dd = [[context activeUser] domainDefaults];
// We check if the Sieve server is available *ONLY* if at least one of the option is enabled // 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]) if (!([dd sieveScriptsEnabled] || [dd vacationEnabled] || [dd forwardEnabled]) || [self _isSieveServerAvailable])
{ {
folder = [[[context activeUser] homeFolderInContext: context] mailAccountsFolder: @"Mail" folder = [[[context activeUser] homeFolderInContext: context] mailAccountsFolder: @"Mail"
inContext: context]; inContext: context];
account = [folder lookupName: @"0" inContext: context acquire: NO]; account = [folder lookupName: @"0" inContext: context acquire: NO];
if (![account updateFilters]) if (![account updateFilters])
{ {
results = (id <WOActionResults>) [self responseWithStatus: 502 results = (id <WOActionResults>) [self responseWithStatus: 502
@ -2230,7 +2243,7 @@ static NSArray *reminderValues = nil;
andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"message", nil]]; andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"message", nil]];
} }
} }
if ((v = [o objectForKey: @"settings"])) if ((v = [o objectForKey: @"settings"]))
{ {
[[[user userSettings] source] setValues: v]; [[[user userSettings] source] setValues: v];

View File

@ -194,16 +194,28 @@
</md-select> </md-select>
</md-input-container> </md-input-container>
<md-input-container> <var:if condition="externalAvatarsEnabled">
<label><var:string label:value="Alternate Avatar"/></label> <div layout="row" layout-align="start start">
<md-select ng-model="app.preferences.defaults.SOGoAlternateAvatar"> <md-checkbox flex="20"
<var:foreach list="alternateAvatar" item="item"> ng-model="app.preferences.defaults.SOGoGravatarEnabled"
<md-option var:value="item"> ng-true-value="1"
<var:string value="itemAlternateAvatarText"/> ng-false-value="0"
</md-option> label:aria-label="Use Gravatar">
</var:foreach> <var:string label:value="Use Gravatar"/>
</md-select> </md-checkbox>
</md-input-container> <md-input-container class="md-flex">
<label><var:string label:value="Alternate Avatar"/></label>
<md-select ng-model="app.preferences.defaults.SOGoAlternateAvatar"
ng-disabled="!app.preferences.defaults.SOGoGravatarEnabled">
<var:foreach list="alternateAvatar" item="item">
<md-option var:value="item">
<var:string value="itemAlternateAvatarText"/>
</md-option>
</var:foreach>
</md-select>
</md-input-container>
</div>
</var:if>
</div> </div>
</md-content> </md-content>
</md-tab> </md-tab>

View File

@ -60,7 +60,8 @@
if (email && vm.urlEmail != email) { if (email && vm.urlEmail != email) {
// Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat) // Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat)
showGenericAvatar(); showGenericAvatar();
getGravatar(email); if (Preferences.defaults.SOGoGravatarEnabled)
getGravatar(email);
} }
else if (!email) else if (!email)
showGenericAvatar(); showGenericAvatar();