feat(preferences): Add SOGoCreateIdentitiesDisabled domain option which disables identity creation for users in preferences

This commit is contained in:
smizrahi
2023-04-18 16:57:31 +02:00
parent 5500ce7085
commit af6202bee6
6 changed files with 126 additions and 24 deletions

View File

@@ -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`.
|=======================================================================

View File

@@ -96,6 +96,8 @@
- (NSDictionary *) mailJunkSettings;
- (BOOL) createIdentitiesDisabled;
@end
#endif /* SOGODOMAINDEFAULTS_H */

View File

@@ -438,4 +438,9 @@
return [self objectForKey: @"SOGoMailJunkSettings"];
}
- (BOOL) createIdentitiesDisabled
{
return [self boolForKey: @"SOGoCreateIdentitiesDisabled"];
}
@end

View File

@@ -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;

View File

@@ -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"])

View File

@@ -24,6 +24,7 @@
<md-dialog-content>
<md-tabs class="md-flex" md-border-bottom="md-border-bottom" md-dynamic-height="true">
<!-- general settings -->
<md-tab id="accountSettingsView" label:label="Settings">
<md-content class="md-padding">
@@ -127,11 +128,13 @@
<i ng-bind-html="$AccountDialogController.account.getTextSignature(identity)"><!-- signature --></i>
</div>
</div>
<md-button class="sg-icon-button" type="button"
ng-click="$AccountDialogController.removeIdentity($index)"
ng-show="$AccountDialogController.canRemoveIdentity($index)">
<md-icon>delete</md-icon>
</md-button>
<var:if condition="showCreateIdentity">
<md-button class="sg-icon-button" type="button"
ng-click="$AccountDialogController.removeIdentity($index)"
ng-show="$AccountDialogController.canRemoveIdentity($index)">
<md-icon>delete</md-icon>
</md-button>
</var:if>
<md-button class="sg-icon-button"
label:aria-label="Default Identity"
ng-click="$AccountDialogController.setDefaultIdentity($event, $index)">
@@ -147,27 +150,48 @@
ng-disabled="$AccountDialogController.customFromIsReadonly()"
ng-model="identity.fullName"/>
</md-input-container>
<md-autocomplete
class="md-block" required="required"
md-no-cache="true"
md-search-text="identity.email"
md-items="address in $AccountDialogController.filterEmailAddresses(identity.email)"
md-escape-options="clear"
md-require-match="$AccountDialogController.customFromIsReadonly()"
md-min-length="0"
label:md-floating-label="Email">
<md-item-template>
<span md-highlight-text="identity.email"
md-highlight-flags="gi">{{ address }}</span>
</md-item-template>
</md-autocomplete>
<var:if condition="showCreateIdentity">
<md-autocomplete
class="md-block" required="required"
md-no-cache="true"
md-search-text="identity.email"
md-items="address in $AccountDialogController.filterEmailAddresses(identity.email)"
md-escape-options="clear"
md-require-match="$AccountDialogController.customFromIsReadonly()"
md-min-length="0"
label:md-floating-label="Email">
<md-item-template>
<span md-highlight-text="identity.email"
md-highlight-flags="gi">{{ address }}</span>
</md-item-template>
</md-autocomplete>
</var:if>
<var:if condition="hideCreateIdentity">
<md-input-container class="md-block"
ng-hide="$AccountDialogController.customFromIsReadonly()">
<label><var:string label:value="Email"/></label>
<input type="text"
autocomplete="off"
ng-model="identity.email"
ng-disabled="true" />
</md-input-container>
</var:if>
<md-input-container class="md-block"
ng-hide="$AccountDialogController.customFromIsReadonly()">
<var:if condition="showCreateIdentity">
<label><var:string label:value="Reply To Email"/></label>
<input type="text"
autocomplete="off"
ng-model="identity.replyTo"
ng-pattern="$AccountDialogController.emailRE"/>
autocomplete="off"
ng-model="identity.replyTo"
ng-pattern="$AccountDialogController.emailRE"/>
</var:if>
<var:if condition="hideCreateIdentity">
<label><var:string label:value="Reply To Email"/></label>
<input type="text"
autocomplete="off"
ng-model="identity.replyTo"
ng-disabled="true" />
</var:if>
</md-input-container>
<md-input-container
class="md-block md-flex"
@@ -187,11 +211,13 @@
</md-card-content>
</md-card>
<div layout="row" layout-align="end center">
<var:if condition="showCreateIdentity">
<md-button type="button"
ng-click="$AccountDialogController.addIdentity()"
label:aria-label="New Identity">
<var:string label:value="New Identity"/>
</md-button>
</var:if>
</div>
</div>