mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-12 07:17:12 +00:00
feat(preferences): Add SOGoCreateIdentitiesDisabled domain option which disables identity creation for users in preferences
This commit is contained in:
1 parent
5500ce7085
commit
af6202bee6
6 files changed
+126
-24
No files matched your search
@@ -810,6 +810,9 @@ specified as an array of dictionaries.
|
|||||||
|S |SOGoJWTSecret
|
|S |SOGoJWTSecret
|
||||||
|JWT secret according to RFC-7519. Default value is `SOGo`.
|
|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;
|
- (NSDictionary *) mailJunkSettings;
|
||||||
|
|
||||||
|
- (BOOL) createIdentitiesDisabled;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* SOGODOMAINDEFAULTS_H */
|
#endif /* SOGODOMAINDEFAULTS_H */
|
||||||
@@ -438,4 +438,9 @@
|
|||||||
return [self objectForKey: @"SOGoMailJunkSettings"];
|
return [self objectForKey: @"SOGoMailJunkSettings"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) createIdentitiesDisabled
|
||||||
|
{
|
||||||
|
return [self boolForKey: @"SOGoCreateIdentitiesDisabled"];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -66,6 +66,20 @@
|
|||||||
return [dd mailCertificateEnabled];
|
return [dd mailCertificateEnabled];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) showCreateIdentity
|
||||||
|
{
|
||||||
|
SOGoDomainDefaults *dd;
|
||||||
|
|
||||||
|
dd = [[context activeUser] domainDefaults];
|
||||||
|
|
||||||
|
return ![dd createIdentitiesDisabled];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) hideCreateIdentity
|
||||||
|
{
|
||||||
|
return ![self showCreateIdentity];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL) _validateFilterId
|
- (BOOL) _validateFilterId
|
||||||
{
|
{
|
||||||
NSCharacterSet *digits;
|
NSCharacterSet *digits;
|
||||||
|
|||||||
@@ -1344,12 +1344,64 @@ static NSArray *reminderValues = nil;
|
|||||||
inDictionary: (NSMutableDictionary *) target
|
inDictionary: (NSMutableDictionary *) target
|
||||||
{
|
{
|
||||||
NSArray *identities;
|
NSArray *identities;
|
||||||
|
SOGoDomainDefaults *dd;
|
||||||
|
NSMutableArray *previousIdentities, *newIdentities;
|
||||||
|
NSMutableDictionary *identity, *newIdentitiesAsDict;
|
||||||
|
int i;
|
||||||
|
|
||||||
if ([account isKindOfClass: [NSDictionary class]])
|
if ([account isKindOfClass: [NSDictionary class]])
|
||||||
{
|
{
|
||||||
|
|
||||||
identities = [account objectForKey: @"identities"];
|
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])
|
if ([[account objectForKey: @"forceDefaultIdentity"] boolValue])
|
||||||
[target setObject: [NSNumber numberWithBool: YES] forKey: @"SOGoMailForceDefaultIdentity"];
|
[target setObject: [NSNumber numberWithBool: YES] forKey: @"SOGoMailForceDefaultIdentity"];
|
||||||
else if ([target objectForKey: @"SOGoMailForceDefaultIdentity"])
|
else if ([target objectForKey: @"SOGoMailForceDefaultIdentity"])
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<md-dialog-content>
|
<md-dialog-content>
|
||||||
<md-tabs class="md-flex" md-border-bottom="md-border-bottom" md-dynamic-height="true">
|
<md-tabs class="md-flex" md-border-bottom="md-border-bottom" md-dynamic-height="true">
|
||||||
|
|
||||||
|
|
||||||
<!-- general settings -->
|
<!-- general settings -->
|
||||||
<md-tab id="accountSettingsView" label:label="Settings">
|
<md-tab id="accountSettingsView" label:label="Settings">
|
||||||
<md-content class="md-padding">
|
<md-content class="md-padding">
|
||||||
@@ -127,11 +128,13 @@
|
|||||||
<i ng-bind-html="$AccountDialogController.account.getTextSignature(identity)"><!-- signature --></i>
|
<i ng-bind-html="$AccountDialogController.account.getTextSignature(identity)"><!-- signature --></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<md-button class="sg-icon-button" type="button"
|
<var:if condition="showCreateIdentity">
|
||||||
ng-click="$AccountDialogController.removeIdentity($index)"
|
<md-button class="sg-icon-button" type="button"
|
||||||
ng-show="$AccountDialogController.canRemoveIdentity($index)">
|
ng-click="$AccountDialogController.removeIdentity($index)"
|
||||||
<md-icon>delete</md-icon>
|
ng-show="$AccountDialogController.canRemoveIdentity($index)">
|
||||||
</md-button>
|
<md-icon>delete</md-icon>
|
||||||
|
</md-button>
|
||||||
|
</var:if>
|
||||||
<md-button class="sg-icon-button"
|
<md-button class="sg-icon-button"
|
||||||
label:aria-label="Default Identity"
|
label:aria-label="Default Identity"
|
||||||
ng-click="$AccountDialogController.setDefaultIdentity($event, $index)">
|
ng-click="$AccountDialogController.setDefaultIdentity($event, $index)">
|
||||||
@@ -147,27 +150,48 @@
|
|||||||
ng-disabled="$AccountDialogController.customFromIsReadonly()"
|
ng-disabled="$AccountDialogController.customFromIsReadonly()"
|
||||||
ng-model="identity.fullName"/>
|
ng-model="identity.fullName"/>
|
||||||
</md-input-container>
|
</md-input-container>
|
||||||
<md-autocomplete
|
<var:if condition="showCreateIdentity">
|
||||||
class="md-block" required="required"
|
<md-autocomplete
|
||||||
md-no-cache="true"
|
class="md-block" required="required"
|
||||||
md-search-text="identity.email"
|
md-no-cache="true"
|
||||||
md-items="address in $AccountDialogController.filterEmailAddresses(identity.email)"
|
md-search-text="identity.email"
|
||||||
md-escape-options="clear"
|
md-items="address in $AccountDialogController.filterEmailAddresses(identity.email)"
|
||||||
md-require-match="$AccountDialogController.customFromIsReadonly()"
|
md-escape-options="clear"
|
||||||
md-min-length="0"
|
md-require-match="$AccountDialogController.customFromIsReadonly()"
|
||||||
label:md-floating-label="Email">
|
md-min-length="0"
|
||||||
<md-item-template>
|
label:md-floating-label="Email">
|
||||||
<span md-highlight-text="identity.email"
|
<md-item-template>
|
||||||
md-highlight-flags="gi">{{ address }}</span>
|
<span md-highlight-text="identity.email"
|
||||||
</md-item-template>
|
md-highlight-flags="gi">{{ address }}</span>
|
||||||
</md-autocomplete>
|
</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"
|
<md-input-container class="md-block"
|
||||||
ng-hide="$AccountDialogController.customFromIsReadonly()">
|
ng-hide="$AccountDialogController.customFromIsReadonly()">
|
||||||
|
<var:if condition="showCreateIdentity">
|
||||||
<label><var:string label:value="Reply To Email"/></label>
|
<label><var:string label:value="Reply To Email"/></label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
ng-model="identity.replyTo"
|
ng-model="identity.replyTo"
|
||||||
ng-pattern="$AccountDialogController.emailRE"/>
|
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>
|
||||||
<md-input-container
|
<md-input-container
|
||||||
class="md-block md-flex"
|
class="md-block md-flex"
|
||||||
@@ -187,11 +211,13 @@
|
|||||||
</md-card-content>
|
</md-card-content>
|
||||||
</md-card>
|
</md-card>
|
||||||
<div layout="row" layout-align="end center">
|
<div layout="row" layout-align="end center">
|
||||||
|
<var:if condition="showCreateIdentity">
|
||||||
<md-button type="button"
|
<md-button type="button"
|
||||||
ng-click="$AccountDialogController.addIdentity()"
|
ng-click="$AccountDialogController.addIdentity()"
|
||||||
label:aria-label="New Identity">
|
label:aria-label="New Identity">
|
||||||
<var:string label:value="New Identity"/>
|
<var:string label:value="New Identity"/>
|
||||||
</md-button>
|
</md-button>
|
||||||
|
</var:if>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user