diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index b768ea92f..055628892 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -810,6 +810,9 @@ specified as an array of dictionaries. |S |SOGoJWTSecret |JWT secret according to RFC-7519. Default value is `SOGo`. +|D |SOGoCreateIdentitiesDisabled +|Disable identity creation for users in preferences. If `YES`, users won't be able to add new identities and will allow to change only full name, signature and default identity. Default value is `NO`. + |======================================================================= diff --git a/SoObjects/SOGo/SOGoDomainDefaults.h b/SoObjects/SOGo/SOGoDomainDefaults.h index 62312a92b..c03c9040d 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.h +++ b/SoObjects/SOGo/SOGoDomainDefaults.h @@ -96,6 +96,8 @@ - (NSDictionary *) mailJunkSettings; +- (BOOL) createIdentitiesDisabled; + @end #endif /* SOGODOMAINDEFAULTS_H */ diff --git a/SoObjects/SOGo/SOGoDomainDefaults.m b/SoObjects/SOGo/SOGoDomainDefaults.m index 56079d554..5e5a6faf6 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.m +++ b/SoObjects/SOGo/SOGoDomainDefaults.m @@ -438,4 +438,9 @@ return [self objectForKey: @"SOGoMailJunkSettings"]; } +- (BOOL) createIdentitiesDisabled +{ + return [self boolForKey: @"SOGoCreateIdentitiesDisabled"]; +} + @end diff --git a/UI/PreferencesUI/UIxAccountEditor.m b/UI/PreferencesUI/UIxAccountEditor.m index abba08d9e..1a7703698 100644 --- a/UI/PreferencesUI/UIxAccountEditor.m +++ b/UI/PreferencesUI/UIxAccountEditor.m @@ -66,6 +66,20 @@ return [dd mailCertificateEnabled]; } +- (BOOL) showCreateIdentity +{ + SOGoDomainDefaults *dd; + + dd = [[context activeUser] domainDefaults]; + + return ![dd createIdentitiesDisabled]; +} + +- (BOOL) hideCreateIdentity +{ + return ![self showCreateIdentity]; +} + - (BOOL) _validateFilterId { NSCharacterSet *digits; diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index f9dc38ede..7ff36bd07 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -1344,12 +1344,64 @@ static NSArray *reminderValues = nil; inDictionary: (NSMutableDictionary *) target { NSArray *identities; + SOGoDomainDefaults *dd; + NSMutableArray *previousIdentities, *newIdentities; + NSMutableDictionary *identity, *newIdentitiesAsDict; + int i; if ([account isKindOfClass: [NSDictionary class]]) { + identities = [account objectForKey: @"identities"]; - if ([self _validateAccountIdentities: identities]) - [target setObject: identities forKey: @"SOGoMailIdentities"]; + + dd = [[context activeUser] domainDefaults]; + if ([self _validateAccountIdentities: identities]) { + // Disable identity creation for users in preferences + if ([dd createIdentitiesDisabled]) { + // If create identities is disabled, user can only modify full name and signature + previousIdentities = [NSMutableArray arrayWithArray: [[user accountWithName: [account objectForKey: @"name"]] objectForKey: @"identities"]]; + newIdentities = [NSMutableArray arrayWithArray: identities]; + + if ([newIdentities count] <= [previousIdentities count]) { + newIdentitiesAsDict = [[NSMutableDictionary alloc] init]; + for (NSDictionary *identity in identities) { + [newIdentitiesAsDict setObject: identity forKey: [identity objectForKey:@"email"]]; + } + + i = 0; + // Remove existing deleted identities + for (identity in [user allIdentities]) { + // Identity deleted and at least one identity and not the default identity + if (![newIdentitiesAsDict objectForKey: [identity objectForKey:@"email"]] + && [previousIdentities count] > 1 + && ![identity boolForKey:@"isDefault"]) { + [previousIdentities removeObjectAtIndex: i]; + i--; + } + i++; + } + + // Update full name, signature and default for existing identities + for (identity in previousIdentities) { + if ([newIdentitiesAsDict objectForKey: [identity objectForKey:@"email"]]) { + [identity setObject: [[newIdentitiesAsDict objectForKey: [identity objectForKey:@"email"]] objectForKey:@"fullName"] forKey: @"fullName"]; + [identity setObject: [[newIdentitiesAsDict objectForKey: [identity objectForKey:@"email"]] objectForKey:@"signature"] forKey: @"signature"]; + if ([[newIdentitiesAsDict objectForKey: [identity objectForKey:@"email"]] objectForKey:@"isDefault"]) { + [identity setObject: [NSNumber numberWithBool: YES] forKey: @"isDefault"]; + } else { + [identity setObject: [NSNumber numberWithBool: NO] forKey: @"isDefault"]; + } + } + } + [newIdentitiesAsDict release]; + } + + [target setObject: previousIdentities forKey: @"SOGoMailIdentities"]; + } else { + [target setObject: identities forKey: @"SOGoMailIdentities"]; + } + } + if ([[account objectForKey: @"forceDefaultIdentity"] boolValue]) [target setObject: [NSNumber numberWithBool: YES] forKey: @"SOGoMailForceDefaultIdentity"]; else if ([target objectForKey: @"SOGoMailForceDefaultIdentity"]) diff --git a/UI/Templates/PreferencesUI/UIxAccountEditor.wox b/UI/Templates/PreferencesUI/UIxAccountEditor.wox index 8f5623fdb..d4dec3803 100644 --- a/UI/Templates/PreferencesUI/UIxAccountEditor.wox +++ b/UI/Templates/PreferencesUI/UIxAccountEditor.wox @@ -24,6 +24,7 @@ + @@ -127,11 +128,13 @@ - - delete - + + + delete + + @@ -147,27 +150,48 @@ ng-disabled="$AccountDialogController.customFromIsReadonly()" ng-model="identity.fullName"/> - - - {{ address }} - - + + + + {{ address }} + + + + + + + + + + + autocomplete="off" + ng-model="identity.replyTo" + ng-pattern="$AccountDialogController.emailRE"/> + + + + +
+ +