diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index 5c37ede74..c1afab83d 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -1173,6 +1173,12 @@ for operations is also bounded by the maximum time that the server is configured to allow. Defaults to `0` (unlimited). + +|D |SOGoLDAPGroupExpansionEnabled +|Parameter used to enable group expansion from the Web interface. + +Defaults to `NO` when unset. + |======================================================================= LDAP Attributes Indexing diff --git a/SoObjects/SOGo/LDAPSource.h b/SoObjects/SOGo/LDAPSource.h index f8fac5d97..b8fee128c 100644 --- a/SoObjects/SOGo/LDAPSource.h +++ b/SoObjects/SOGo/LDAPSource.h @@ -67,6 +67,7 @@ NSString *_domain; NSString *_contactInfoAttribute; + BOOL _groupExpansionEnabled; NSDictionary *_contactMapping; NSArray *_contactObjectClasses; @@ -125,6 +126,8 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField; - (void) updateBaseDNFromLogin: (NSString *) theLogin; +- (BOOL) groupExpansionEnabled; + @end #endif /* LDAPSOURCE_H */ diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index 4ed641d45..7afb3e92b 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -165,7 +165,7 @@ static Class NSStringK; inDomain: (NSString *) sourceDomain { SOGoDomainDefaults *dd; - NSNumber *udQueryLimit, *udQueryTimeout, *dotValue; + NSNumber *udQueryLimit, *udQueryTimeout, *udGroupExpansionEnabled, *dotValue; if ((self = [self init])) { @@ -238,6 +238,14 @@ static Class NSStringK; else _queryTimeout = [dd ldapQueryTimeout]; + if ([[udSource allKeys] containsObject: @"SOGoLDAPGroupExpansionEnabled"]) + { + udGroupExpansionEnabled = [udSource objectForKey: @"SOGoLDAPGroupExpansionEnabled"]; + _groupExpansionEnabled = [udGroupExpansionEnabled boolValue]; + } + else + _groupExpansionEnabled = [dd ldapGroupExpansionEnabled]; + ASSIGN(_modulesConstraints, [udSource objectForKey: @"ModulesConstraints"]); ASSIGN(_filter, [udSource objectForKey: @"filter"]); ASSIGN(_userPasswordAlgorithm, [udSource objectForKey: @"userPasswordAlgorithm"]); @@ -1461,6 +1469,11 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses return _groupObjectClasses; } +- (BOOL) groupExpansionEnabled +{ + return _groupExpansionEnabled; +} + static NSArray * _convertRecordToLDAPAttributes (LDAPSourceSchema *schema, NSDictionary *ldifRecord) { diff --git a/SoObjects/SOGo/SOGoDomainDefaults.h b/SoObjects/SOGo/SOGoDomainDefaults.h index 2379a2a0d..371954726 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.h +++ b/SoObjects/SOGo/SOGoDomainDefaults.h @@ -75,6 +75,8 @@ - (NSArray *) freeBusyDefaultInterval; - (int) davCalendarStartTimeLimit; +- (BOOL) ldapGroupExpansionEnabled; + - (BOOL) iPhoneForceAllDayTransparency; - (NSArray *) additionalJSFiles; diff --git a/SoObjects/SOGo/SOGoDomainDefaults.m b/SoObjects/SOGo/SOGoDomainDefaults.m index dc31ff05e..39fd58888 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.m +++ b/SoObjects/SOGo/SOGoDomainDefaults.m @@ -314,6 +314,11 @@ return [self stringForKey: @"SOGoLDAPContactInfoAttribute"]; } +- (BOOL) ldapGroupExpansionEnabled +{ + return [self boolForKey: @"SOGoLDAPGroupExpansionEnabled"]; +} + - (NSArray *) freeBusyDefaultInterval { return [self arrayForKey: @"SOGoFreeBusyDefaultInterval"]; diff --git a/UI/Contacts/UIxContactView.m b/UI/Contacts/UIxContactView.m index 22e0d69c5..73f22c399 100644 --- a/UI/Contacts/UIxContactView.m +++ b/UI/Contacts/UIxContactView.m @@ -31,7 +31,9 @@ #import #import #import +#import #import +#import #import #import #import @@ -395,42 +397,58 @@ NSMutableDictionary *userData; NSString *email; SOGoObject *contact; + SOGoObject *source; SOGoUser *user; id result; unsigned int i, max; result = nil; contact = [self clientObject]; + source = [[contact container] source]; dict = [[SOGoUserManager sharedUserManager] contactInfosForUserWithUIDorEmail: [contact nameInContainer]]; if ([[dict objectForKey: @"isGroup"] boolValue]) { - SOGoGroup *aGroup; - - aGroup = [SOGoGroup groupWithIdentifier: [contact nameInContainer] - inDomain: [[context activeUser] domain]]; - allUsers = [aGroup members]; // array of SOGoUser objects - max = [allUsers count]; - allUsersData = [NSMutableArray arrayWithCapacity: max]; - for (i = 0; i < max; i++) + if ([source isKindOfClass: [LDAPSource class]] && [(LDAPSource *) source groupExpansionEnabled]) { - user = [allUsers objectAtIndex: i]; - allUserEmails = [NSMutableArray array]; - emails = [[user allEmails] objectEnumerator]; - while ((email = [emails nextObject])) { - [allUserEmails addObject: [NSDictionary dictionaryWithObjectsAndKeys: - email, @"value", @"work", @"type", nil]]; - } - userData = [NSDictionary dictionaryWithObjectsAndKeys: - [user loginInDomain], @"c_uid", - [user cn], @"c_cn", - allUserEmails, @"emails", nil]; - [allUsersData addObject: userData]; + SOGoGroup *aGroup; + + aGroup = [SOGoGroup groupWithIdentifier: [contact nameInContainer] + inDomain: [[context activeUser] domain]]; + allUsers = [aGroup members]; // array of SOGoUser objects + max = [allUsers count]; + allUsersData = [NSMutableArray arrayWithCapacity: max]; + for (i = 0; i < max; i++) + { + user = [allUsers objectAtIndex: i]; + allUserEmails = [NSMutableArray array]; + emails = [[user allEmails] objectEnumerator]; + while ((email = [emails nextObject])) { + [allUserEmails addObject: [NSDictionary dictionaryWithObjectsAndKeys: + email, @"value", @"work", @"type", nil]]; + } + userData = [NSDictionary dictionaryWithObjectsAndKeys: + [user loginInDomain], @"c_uid", + [user cn], @"c_cn", + allUserEmails, @"emails", nil]; + [allUsersData addObject: userData]; + } + dict = [NSDictionary dictionaryWithObject: allUsersData forKey: @"members"]; + result = [self responseWithStatus: 200 + andString: [dict jsonRepresentation]]; + } + else + { + result = [self responseWithStatus: 403 + andString: @"Group is not expandable"]; } - dict = [NSDictionary dictionaryWithObject: allUsersData forKey: @"members"]; - result = [self responseWithStatus: 200 - andString: [dict jsonRepresentation]]; } + else + { + result = [self responseWithStatus: 405 + andString: @"Contact is not a group"]; + } + return result; } diff --git a/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox b/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox index 7b8576688..35346684f 100644 --- a/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox +++ b/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox @@ -70,7 +70,7 @@
{{currentAttendee.name}}
{{currentAttendee.email}}
- + add_box
diff --git a/UI/WebServerResources/js/Scheduler/Attendees.service.js b/UI/WebServerResources/js/Scheduler/Attendees.service.js index 1be77ff40..816fa00c3 100644 --- a/UI/WebServerResources/js/Scheduler/Attendees.service.js +++ b/UI/WebServerResources/js/Scheduler/Attendees.service.js @@ -171,6 +171,7 @@ domain: card.c_domain, isMSExchange: card.ismsexchange, isGroup: card.$isList(), + isExpandableGroup: false, isResource: card.isresource, name: card.c_cn, email: card.$$email, @@ -185,6 +186,7 @@ // LDAP list -- preload members card.$members().then(function(members) { attendee.members = members; + attendee.isExpandableGroup = true; }); } attendee.image = Attendees.$gravatar(attendee.email, 32);