diff --git a/ChangeLog b/ChangeLog index 13d6bcab5..cff90b008 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2009-09-29 Wolfgang Sourdeau + * SoObjects/SOGo/SOGoGroup.m (-members): we now cache the array of + members as an ivar. + (-hasMemberWithUID): new self-explicit method. + + * SoObjects/SOGo/SOGoGCSFolder.m + (_fetchAclsForUser:forObjectAtPath:): refactored method to make it + actually work for group searches, without unitialized data and to + clarify code. + * SoObjects/SOGo/SOGoObject.m (_urlPreferringParticle:overThisOne:): instead of risking confusion between SOPE, NSURL and friends, we revert this change diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index 817d151ad..8976e8b84 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -1190,61 +1190,71 @@ static NSArray *childRecordFields = nil; return uids; } +- (NSArray *) _aclsFromUserRoles: (NSArray *) records + matchingUID: (NSString *) uid +{ + int count, max; + NSDictionary *record; + NSMutableArray *acls; + NSString *currentUID; + + acls = [NSMutableArray array]; + + max = [records count]; + for (count = 0; count < max; count++) + { + record = [records objectAtIndex: count]; + currentUID = [record valueForKey: @"c_uid"]; + if ([currentUID isEqualToString: uid]) + [acls addObject: [record valueForKey: @"c_role"]]; + } + + return acls; +} + +- (NSArray *) _aclsFromGroupRoles: (NSArray *) records + matchingUID: (NSString *) uid +{ + int count, max; + NSDictionary *record; + NSString *currentUID; + SOGoGroup *group; + NSMutableArray *acls; + + acls = [NSMutableArray array]; + + max = [records count]; + for (count = 0; count < max; count++) + { + record = [records objectAtIndex: count]; + currentUID = [record valueForKey: @"c_uid"]; + if ([currentUID hasPrefix: @"@"]) + { + group = [SOGoGroup groupWithIdentifier: currentUID]; + if (group && [group hasMemberWithUID: uid]) + [acls addObject: [record valueForKey: @"c_role"]]; + } + } + + return acls; +} + - (NSArray *) _fetchAclsForUser: (NSString *) uid forObjectAtPath: (NSString *) objectPath { EOQualifier *qualifier; - NSArray *records; - NSMutableArray *acls; + NSArray *records, *acls; NSString *qs; - BOOL foundUserAcls; // We look for the exact uid or any uid that begins with "@" (corresponding to groups) qs = [NSString stringWithFormat: @"(c_object = '/%@') AND (c_uid = '%@' OR c_uid LIKE '@%%')", - objectPath, uid]; + objectPath, uid]; qualifier = [EOQualifier qualifierWithQualifierFormat: qs]; records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier]; - acls = [NSMutableArray array]; - unsigned int i, j; - NSArray *members; - NSDictionary *record; - NSString *currentUid; - SOGoGroup *group; - SOGoUser *user; - - foundUserAcls = NO; - - for (i = 0; i < [records count]; i ++) - { - record = [records objectAtIndex: i]; - currentUid = [record valueForKey: @"c_uid"]; - if ([currentUid isEqualToString: uid]) - { - [acls addObject: [record valueForKey: @"c_role"]]; - foundUserAcls = YES; - } - } - if (!foundUserAcls) - { - for (i = 0; i < [records count]; i ++) - { - group = [SOGoGroup groupWithIdentifier: currentUid]; - if (group) - { - members = [group members]; - for (j = 0; j < [members count]; j++) - { - user = [members objectAtIndex: j]; - if ([[user login] isEqualToString: uid]) - { - [acls addObject: [record valueForKey: @"c_role"]]; - break; - } - } - } - } - } + acls = [self _aclsFromUserRoles: records matchingUID: uid]; + if (![acls count]) + acls = [self _aclsFromGroupRoles: records matchingUID: uid]; return [acls uniqueObjects]; } diff --git a/SoObjects/SOGo/SOGoGroup.m b/SoObjects/SOGo/SOGoGroup.m index 0e54ef02d..2fd3a3ae0 100644 --- a/SoObjects/SOGo/SOGoGroup.m +++ b/SoObjects/SOGo/SOGoGroup.m @@ -71,6 +71,7 @@ ASSIGN(_identifier, theID); ASSIGN(_source, theSource); ASSIGN(_entry, theEntry); + _members = nil; } return self; @@ -81,6 +82,7 @@ RELEASE(_identifier); RELEASE(_source); RELEASE(_entry); + RELEASE(_members); [super dealloc]; } @@ -90,12 +92,15 @@ NSString *uid; uid = [theID hasPrefix: @"@"] ? [theID substringFromIndex: 1] : theID; - return [SOGoGroup groupWithValue: uid andSourceSelector: @selector (lookupGroupEntryByUID:)]; + + return [SOGoGroup groupWithValue: uid + andSourceSelector: @selector (lookupGroupEntryByUID:)]; } + (id) groupWithEmail: (NSString *) theEmail { - return [SOGoGroup groupWithValue: theEmail andSourceSelector: @selector (lookupGroupEntryByEmail:)]; + return [SOGoGroup groupWithValue: theEmail + andSourceSelector: @selector (lookupGroupEntryByEmail:)]; } // @@ -163,71 +168,92 @@ - (NSArray *) members { NSMutableArray *dns, *uids; - NSMutableArray *array; NSString *dn, *login; SOGoUser *user; NSArray *o; SOGoUserManager *um; int i, c; - array = [NSMutableArray array]; - uids = [NSMutableArray array]; - dns = [NSMutableArray array]; - - // We check if it's a static group - //NSLog(@"attributes = %@", [_entry attributes]); - - // Fetch "members" - we get DNs - o = [[_entry attributeWithName: @"member"] allStringValues]; - if (o) [dns addObjectsFromArray: o]; - - // Fetch "uniqueMembers" - we get DNs - o = [[_entry attributeWithName: @"uniqueMember"] allStringValues]; - if (o) [dns addObjectsFromArray: o]; - - // Fetch "memberUid" - we get UID (like login names) - o = [[_entry attributeWithName: @"memberUid"] allStringValues]; - if (o) [uids addObjectsFromArray: o]; - - c = [dns count] + [uids count]; - - NSLog(@"members count (static group): %d", c); - - // We deal with a static group, let's add the members - if (c) + if (!_members) { - um = [SOGoUserManager sharedUserManager]; + _members = [NSMutableArray new]; + uids = [NSMutableArray array]; + dns = [NSMutableArray array]; - // We add members for whom we have their associated DN - for (i = 0; i < [dns count]; i++) - { - dn = [dns objectAtIndex: i]; - login = [um getLoginForDN: [dn lowercaseString]]; - //NSLog(@"member = %@", login); - user = [SOGoUser userWithLogin: login roles: nil]; - if (user) - [array addObject: user]; - } + // We check if it's a static group + //NSLog(@"attributes = %@", [_entry attributes]); + + // Fetch "members" - we get DNs + o = [[_entry attributeWithName: @"member"] allStringValues]; + if (o) [dns addObjectsFromArray: o]; - // We add members for whom we have their associated login name - for (i = 0; i < [uids count]; i++) - { - login = [uids objectAtIndex: i]; - //NSLog(@"member = %@", login); - user = [SOGoUser userWithLogin: login roles: nil]; - - if (user) - [array addObject: user]; - } - } - else - { - // We deal with a dynamic group, let's search all users for whom - // memberOf is equal to our group's DN. - // We also need to look for labelelURI? + // Fetch "uniqueMembers" - we get DNs + o = [[_entry attributeWithName: @"uniqueMember"] allStringValues]; + if (o) [dns addObjectsFromArray: o]; + + // Fetch "memberUid" - we get UID (like login names) + o = [[_entry attributeWithName: @"memberUid"] allStringValues]; + if (o) [uids addObjectsFromArray: o]; + + c = [dns count] + [uids count]; + + NSLog(@"members count (static group): %d", c); + + // We deal with a static group, let's add the members + if (c) + { + um = [SOGoUserManager sharedUserManager]; + + // We add members for whom we have their associated DN + for (i = 0; i < [dns count]; i++) + { + dn = [dns objectAtIndex: i]; + login = [um getLoginForDN: [dn lowercaseString]]; + //NSLog(@"member = %@", login); + user = [SOGoUser userWithLogin: login roles: nil]; + if (user) + [_members addObject: user]; + } + + // We add members for whom we have their associated login name + for (i = 0; i < [uids count]; i++) + { + login = [uids objectAtIndex: i]; + //NSLog(@"member = %@", login); + user = [SOGoUser userWithLogin: login roles: nil]; + + if (user) + [_members addObject: user]; + } + } + else + { + // We deal with a dynamic group, let's search all users for whom + // memberOf is equal to our group's DN. + // We also need to look for labelelURI? + } } - return array; + return _members; +} + +- (BOOL) hasMemberWithUID: (NSString *) memberUID +{ + int count, max; + NSString *currentUID; + BOOL rc; + + rc = NO; + + [self members]; + max = [_members count]; + for (count = 0; !rc && count < max; count++) + { + currentUID = [[_members objectAtIndex: count] login]; + rc = [memberUID isEqualToString: currentUID]; + } + + return rc; } @end