mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-02-22 01:46:23 +00:00
feat(preferences): Add SOGoCreateIdentitiesDisabled domain option which disables identity creation for users in preferences
This commit is contained in:
@@ -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`.
|
||||
|
||||
|
||||
|
||||
|=======================================================================
|
||||
|
||||
@@ -96,6 +96,8 @@
|
||||
|
||||
- (NSDictionary *) mailJunkSettings;
|
||||
|
||||
- (BOOL) createIdentitiesDisabled;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SOGODOMAINDEFAULTS_H */
|
||||
|
||||
@@ -438,4 +438,9 @@
|
||||
return [self objectForKey: @"SOGoMailJunkSettings"];
|
||||
}
|
||||
|
||||
- (BOOL) createIdentitiesDisabled
|
||||
{
|
||||
return [self boolForKey: @"SOGoCreateIdentitiesDisabled"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user