Skip to content

Commit

Permalink
feat(mail): handle multiple mail identities
Browse files Browse the repository at this point in the history
Fixes #768, fixes #4602
  • Loading branch information
cgx committed Jun 18, 2020
1 parent 2651b5a commit f8aa338
Show file tree
Hide file tree
Showing 24 changed files with 599 additions and 420 deletions.
7 changes: 4 additions & 3 deletions SoObjects/Mailer/SOGoDraftObject.m
Expand Up @@ -995,7 +995,7 @@ - (void) fetchMailForReplying: (SOGoMailObject *) sourceMail
- (void) fetchMailForForwarding: (SOGoMailObject *) sourceMail
{
NSDictionary *info, *attachment;
NSString *signature, *nl;
NSString *signature, *nl, *space;
SOGoUserDefaults *ud;

[sourceMail fetchCoreInfos];
Expand Down Expand Up @@ -1031,8 +1031,9 @@ - (void) fetchMailForForwarding: (SOGoMailObject *) sourceMail
signature = [[self mailAccountFolder] signature];
if ([signature length])
{
nl = (isHTML ? @"<br/>" : @"\n");
[self setText: [NSString stringWithFormat: @"%@%@-- %@%@", nl, nl, nl, signature]];
nl = (isHTML ? @"<br />" : @"\n");
space = (isHTML ? @"&nbsp;" : @" ");
[self setText: [NSString stringWithFormat: @"%@%@--%@%@%@", nl, nl, space, nl, signature]];
}
attachment = [NSDictionary dictionaryWithObjectsAndKeys:
[sourceMail filenameForForward], @"filename",
Expand Down
3 changes: 2 additions & 1 deletion SoObjects/Mailer/SOGoMailAccount.h
@@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2019 Inverse inc.
Copyright (C) 2009-2020 Inverse inc.
This file is part of SOGo.
Expand Down Expand Up @@ -87,6 +87,7 @@ typedef enum {
forceActivation: (BOOL) forceActivation;

- (NSArray *) identities;
- (NSDictionary *) defaultIdentity;
- (NSString *) signature;
- (NSString *) encryption;

Expand Down
32 changes: 28 additions & 4 deletions SoObjects/Mailer/SOGoMailAccount.m
@@ -1,5 +1,5 @@
/*
Copyright (C) 2007-2019 Inverse inc.
Copyright (C) 2007-2020 Inverse inc.
This file is part of SOGo.
Expand Down Expand Up @@ -667,13 +667,37 @@ - (NSArray *) identities
return identities;
}

- (NSDictionary *) defaultIdentity
{
NSDictionary *defaultIdentity, *currentIdentity;
unsigned int count, max;

defaultIdentity = nil;
[self identities];

max = [identities count];
for (count = 0; count < max; count++)
{
currentIdentity = [identities objectAtIndex: count];
if ([[currentIdentity objectForKey: @"isDefault"] boolValue])
{
defaultIdentity = currentIdentity;
break;
}
}

return defaultIdentity; // can be nil
}

- (NSString *) signature
{
NSDictionary *identity;
NSString *signature;

[self identities];
if ([identities count] > 0)
signature = [[identities objectAtIndex: 0] objectForKey: @"signature"];
identity = [self defaultIdentity];

if (identity)
signature = [identity objectForKey: @"signature"];
else
signature = nil;

Expand Down
7 changes: 4 additions & 3 deletions SoObjects/Mailer/SOGoMailForward.m
Expand Up @@ -234,14 +234,15 @@ - (NSString *) messageBody

- (NSString *) signature
{
NSString *signature, *mailSignature, *nl;
NSString *signature, *mailSignature, *nl, *space;

signature = [[sourceMail mailAccountFolder] signature];

if ([signature length])
{
nl = (htmlComposition ? @"<br/>" : @"\n");
mailSignature = [NSString stringWithFormat: @"-- %@%@", nl, signature];
nl = (htmlComposition ? @"<br />" : @"\n");
space = (htmlComposition ? @"&nbsp;" : @" ");
mailSignature = [NSString stringWithFormat: @"--%@%@%@", space, nl, signature];
}
else
mailSignature = @"";
Expand Down
173 changes: 92 additions & 81 deletions SoObjects/SOGo/SOGoUser.m
Expand Up @@ -342,18 +342,34 @@ - (NSString *) cn

- (NSMutableDictionary *) defaultIdentity
{
NSMutableDictionary *currentIdentity, *defaultIdentity;
NSEnumerator *identities;
NSDictionary *defaultAccount, *currentIdentity;
NSMutableDictionary *defaultIdentity;
NSArray *identities;
NSString *defaultEmail;
unsigned int count, max;

defaultEmail = [NSString stringWithFormat: @"%@@%@", [self loginInDomain], [self domain]];
defaultAccount = [[self mailAccounts] objectAtIndex: 0];
defaultIdentity = nil;

identities = [[self allIdentities] objectEnumerator];
while (!defaultIdentity
&& (currentIdentity = [identities nextObject]))
if ([[currentIdentity objectForKey: @"isDefault"] boolValue])
defaultIdentity = currentIdentity;
identities = [defaultAccount objectForKey: @"identities"];
max = [identities count];

return defaultIdentity;
for (count = 0; count < max; count++)
{
currentIdentity = [identities objectAtIndex: count];
if ([[currentIdentity objectForKey: @"isDefault"] boolValue])
{
defaultIdentity = [NSMutableDictionary dictionaryWithDictionary: currentIdentity];
break;
}
else if ([[currentIdentity objectForKey: @"email"] caseInsensitiveCompare: defaultEmail] == NSOrderedSame)
{
defaultIdentity = [NSMutableDictionary dictionaryWithDictionary: currentIdentity];
}
}

return defaultIdentity; // can be nil
}

- (SOGoDateFormatter *) dateFormatterInContext: (WOContext *) context
Expand Down Expand Up @@ -626,19 +642,20 @@ - (void) _migrateFolderSettings

- (void) _appendSystemMailAccountWithDelegatedIdentities: (BOOL) appendDeletegatedIdentities
{
NSString *fullName, *replyTo, *imapLogin, *imapServer, *cImapServer, *signature,
*encryption, *scheme, *action, *query, *customEmail, *defaultEmail, *sieveServer;
NSString *fullName, *imapLogin, *imapServer, *cImapServer,
*encryption, *scheme, *action, *query, *customEmail, *sieveServer;
NSMutableDictionary *mailAccount, *identity, *mailboxes, *receipts, *security, *mailSettings;
NSNumber *port;
NSMutableArray *identities, *mails;
NSArray *delegators, *delegates;
NSURL *url, *cUrl;
unsigned int count, max, default_identity;
unsigned int count, max; //, default_identity;
NSInteger defaultPort;
NSUInteger index;
BOOL hasDefaultIdentity;

[self userDefaults];
[self userSettings];
[self userDefaults]; // set _defaults
[self userSettings]; // set _settings

mailSettings = [_settings objectForKey: @"Mail"];
mailAccount = [NSMutableDictionary new];
Expand Down Expand Up @@ -715,89 +732,75 @@ - (void) _appendSystemMailAccountWithDelegatedIdentities: (BOOL) appendDeletegat
}

// 5. Identities
defaultEmail = [NSString stringWithFormat: @"%@@%@", [self loginInDomain], [self domain]];
default_identity = 0;
identities = [NSMutableArray new];
[identities addObjectsFromArray: [_defaults mailIdentities]];
mails = [NSMutableArray arrayWithArray: [self allEmails]];
[mailAccount setObject: [mails objectAtIndex: 0] forKey: @"name"];
max = [identities count];
hasDefaultIdentity = NO;
fullName = [self cn];
if ([fullName length] == 0)
fullName = login;

replyTo = [_defaults mailReplyTo];

max = [mails count];

/* custom from */
if ([[self domainDefaults] mailCustomFromEnabled])
// Sanitize identities
for (count = 0; count < max; count++)
{
[self userDefaults];
customEmail = [_defaults mailCustomEmail];
fullName = [_defaults mailCustomFullName];
if ([customEmail length] > 0 || [fullName length] > 0)
identity = [NSMutableDictionary dictionaryWithDictionary: [identities objectAtIndex: count]];
customEmail = [identity objectForKey: @"email"];
if ([customEmail length])
{
if ([customEmail length] == 0)
customEmail = [mails objectAtIndex: 0];
else if ([fullName length] == 0)
if (![[self domainDefaults] mailCustomFromEnabled])
{
// Custom email but default fullname; if the custom email is
// one of the user's emails, remove the duplicated entry
// No custom from -- enforce a valid email
index = [mails indexOfObject: customEmail];
if (index != NSNotFound)
if (index == NSNotFound)
{
[mails removeObjectAtIndex: index];
max--;
[identity setObject: [self systemEmail] forKey: @"email"];
}
}

if ([fullName length] == 0)
{
fullName = [self cn];
if ([fullName length] == 0)
fullName = login;
}

identity = [NSMutableDictionary new];
[identity setObject: customEmail forKey: @"email"];
}
else
{
// Email must be defined
[identity setObject: [self systemEmail] forKey: @"email"];
}
if (![[self domainDefaults] mailCustomFromEnabled])
{
// No custom from -- enforce a valid fullname and remove reply-to
[identity setObject: fullName forKey: @"fullName"];

if ([replyTo length] > 0)
[identity setObject: replyTo forKey: @"replyTo"];

signature = [_defaults mailSignature];
if (signature)
[identity setObject: signature forKey: @"signature"];
[identities addObject: identity];

if ([[identity objectForKey: @"email"] caseInsensitiveCompare: defaultEmail] == NSOrderedSame)
default_identity = [identities count]-1;

[identity release];
[identity removeObjectForKey: @"replyTo"];
}
if (!appendDeletegatedIdentities)
{
[identity setObject: [NSNumber numberWithBool: YES] forKey: @"isReadOnly"];
}
if ([[identity objectForKey: @"isDefault"] boolValue])
{
if (hasDefaultIdentity || !appendDeletegatedIdentities)
[identity removeObjectForKey: @"isDefault"]; // only one possible default identity
else
hasDefaultIdentity = YES;
}
[identities replaceObjectAtIndex: count withObject: identity];
}

for (count = 0; count < max; count++)
if (![identities count])
{
identity = [NSMutableDictionary new];
fullName = [self cn];
if (![fullName length])
fullName = login;
[identity setObject: fullName forKey: @"fullName"];
[identity setObject: [[mails objectAtIndex: count] stringByTrimmingSpaces]
forKey: @"email"];

if ([replyTo length] > 0)
[identity setObject: replyTo forKey: @"replyTo"];

signature = [_defaults mailSignature];
if (signature)
[identity setObject: signature forKey: @"signature"];
// Create a default identity
identity = [NSMutableDictionary dictionaryWithObjectsAndKeys:
fullName, @"fullName",
[self systemEmail], @"email", nil];
if (appendDeletegatedIdentities)
{
[identity setObject: [NSNumber numberWithBool: YES] forKey: @"isDefault"];
hasDefaultIdentity = YES;
}
else
{
[identity setObject: [NSNumber numberWithBool: YES] forKey: @"isReadOnly"];
}
[identities addObject: identity];

if ([[identity objectForKey: @"email"] caseInsensitiveCompare: defaultEmail] == NSOrderedSame)
default_identity = [identities count]-1;

[identity release];
}
[[identities objectAtIndex: default_identity] setObject: [NSNumber numberWithBool: YES]
forKey: @"isDefault"];

/* identities from delegators */
if (appendDeletegatedIdentities)
Expand Down Expand Up @@ -980,11 +983,19 @@ - (NSArray *) allIdentities

- (NSDictionary *) primaryIdentity
{
NSDictionary *defaultAccount;
NSArray *identities;
NSDictionary *defaultIdentity, *defaultAccount;

defaultAccount = [[self mailAccounts] objectAtIndex: 0];
defaultIdentity = [self defaultIdentity];

if (!defaultIdentity && [[self mailAccounts] count])
{
defaultAccount = [[self mailAccounts] objectAtIndex: 0];
identities = [defaultAccount objectForKey: @"identities"];
defaultIdentity = [identities objectAtIndex: 0];
}

return [[defaultAccount objectForKey: @"identities"] objectAtIndex: 0];
return defaultIdentity;
}

/* folders */
Expand Down
17 changes: 4 additions & 13 deletions SoObjects/SOGo/SOGoUserDefaults.h
@@ -1,6 +1,6 @@
/* SOGoUserDefaults.h - this file is part of SOGo
*
* Copyright (C) 2011-2017 Inverse inc.
* Copyright (C) 2011-2020 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
Expand Down Expand Up @@ -157,21 +157,9 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (void) setMailReplyPlacement: (NSString *) newValue;
- (NSString *) mailReplyPlacement;

- (void) setMailSignature: (NSString *) newValue;
- (NSString *) mailSignature;

- (void) setMailSignaturePlacement: (NSString *) newValue;
- (NSString *) mailSignaturePlacement;

- (void) setMailCustomFullName: (NSString *) newValue;
- (NSString *) mailCustomFullName;

- (void) setMailCustomEmail: (NSString *) newValue;
- (NSString *) mailCustomEmail;

- (void) setMailReplyTo: (NSString *) newValue;
- (NSString *) mailReplyTo;

- (void) setAllowUserReceipt: (BOOL) allow;
- (BOOL) allowUserReceipt;
- (void) setUserReceiptNonRecipientAction: (NSString *) action;
Expand All @@ -194,6 +182,9 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (void) setMailCertificateAlwaysEncrypt: (BOOL) newValue;
- (BOOL) mailCertificateAlwaysEncrypt;

- (void) setMailIdentities: (NSArray *) newIdentites;
- (NSArray *) mailIdentities;

- (void) setAuxiliaryMailAccounts: (NSArray *) newAccounts;
- (NSArray *) auxiliaryMailAccounts;

Expand Down

0 comments on commit f8aa338

Please sign in to comment.