Skip to content

Commit ee01068

Browse files
authored
Merge pull request #8537 from nextcloud/8522-stable12
[stable12] Fix retrieval of group members with numerical uids from LDAP
2 parents 1489474 + 0b51ce6 commit ee01068

File tree

2 files changed

+91
-7
lines changed

2 files changed

+91
-7
lines changed

apps/user_ldap/lib/Group_LDAP.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ public function getDynamicGroupMembers($dnGroup) {
199199
* @param string $dnGroup
200200
* @param array|null &$seen
201201
* @return array|mixed|null
202+
* @throws \OC\ServerNotAvailableException
202203
*/
203204
private function _groupMembers($dnGroup, &$seen = null) {
204205
if ($seen === null) {
@@ -212,26 +213,26 @@ private function _groupMembers($dnGroup, &$seen = null) {
212213
// used extensively in cron job, caching makes sense for nested groups
213214
$cacheKey = '_groupMembers'.$dnGroup;
214215
$groupMembers = $this->access->connection->getFromCache($cacheKey);
215-
if(!is_null($groupMembers)) {
216+
if($groupMembers !== null) {
216217
return $groupMembers;
217218
}
218219
$seen[$dnGroup] = 1;
219220
$members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr,
220221
$this->access->connection->ldapGroupFilter);
221222
if (is_array($members)) {
222-
foreach ($members as $memberDN) {
223-
$allMembers[$memberDN] = 1;
223+
foreach ($members as $member) {
224+
$allMembers[$member] = 1;
224225
$nestedGroups = $this->access->connection->ldapNestedGroups;
225226
if (!empty($nestedGroups)) {
226-
$subMembers = $this->_groupMembers($memberDN, $seen);
227+
$subMembers = $this->_groupMembers($member, $seen);
227228
if ($subMembers) {
228-
$allMembers = array_merge($allMembers, $subMembers);
229+
$allMembers += $subMembers;
229230
}
230231
}
231232
}
232233
}
233234

234-
$allMembers = array_merge($allMembers, $this->getDynamicGroupMembers($dnGroup));
235+
$allMembers += $this->getDynamicGroupMembers($dnGroup);
235236

236237
$this->access->connection->writeToCache($cacheKey, $allMembers);
237238
return $allMembers;

apps/user_ldap/tests/Group_LDAPTest.php

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
use OCA\User_LDAP\Group_LDAP as GroupLDAP;
3333
use OCA\User_LDAP\ILDAPWrapper;
34+
use Test\TestCase;
3435

3536
/**
3637
* Class GroupLDAPTest
@@ -39,7 +40,7 @@
3940
*
4041
* @package OCA\User_LDAP\Tests
4142
*/
42-
class Group_LDAPTest extends \Test\TestCase {
43+
class Group_LDAPTest extends TestCase {
4344
private function getAccessMock() {
4445
static $conMethods;
4546
static $accMethods;
@@ -653,4 +654,86 @@ public function testGetGroupsByMember() {
653654
$groupsAgain = $groupBackend->getUserGroups('userX');
654655
$this->assertEquals(['group1', 'group2'], $groupsAgain);
655656
}
657+
658+
public function groupMemberProvider() {
659+
$base = 'dc=species,dc=earth';
660+
661+
$groups0 = [
662+
'uid=3723,' . $base,
663+
'uid=8372,' . $base,
664+
'uid=8427,' . $base,
665+
'uid=2333,' . $base,
666+
'uid=4754,' . $base,
667+
];
668+
$groups1 = [
669+
'3723',
670+
'8372',
671+
'8427',
672+
'2333',
673+
'4754',
674+
];
675+
$groups2Nested = ['6642', '1424'];
676+
$expGroups2 = array_merge($groups1, $groups2Nested);
677+
678+
return [
679+
[ #0 – test DNs
680+
'cn=Birds,' . $base,
681+
$groups0,
682+
['cn=Birds,' . $base => $groups0]
683+
],
684+
[ #1 – test uids
685+
'cn=Birds,' . $base,
686+
$groups1,
687+
['cn=Birds,' . $base => $groups1]
688+
],
689+
[ #2 – test uids with nested groups
690+
'cn=Birds,' . $base,
691+
$expGroups2,
692+
[
693+
'cn=Birds,' . $base => $groups1,
694+
'8427' => $groups2Nested, // simplified - nested groups would work with DNs
695+
],
696+
],
697+
];
698+
}
699+
700+
/**
701+
* @param string $groupDN
702+
* @param string[] $expectedMembers
703+
* @param array $groupsInfo
704+
* @dataProvider groupMemberProvider
705+
*/
706+
public function testGroupMembers($groupDN, $expectedMembers, $groupsInfo = null) {
707+
$access = $this->getAccessMock();
708+
$access->expects($this->any())
709+
->method('readAttribute')
710+
->willReturnCallback(function($group) use ($groupDN, $expectedMembers, $groupsInfo) {
711+
if(isset($groupsInfo[$group])) {
712+
return $groupsInfo[$group];
713+
}
714+
return [];
715+
});
716+
717+
$access->connection = $this->createMock(Connection::class);
718+
if(count($groupsInfo) > 1) {
719+
$access->connection->expects($this->any())
720+
->method('__get')
721+
->willReturnCallback(function($name) {
722+
if($name === 'ldapNestedGroups') {
723+
return 1;
724+
}
725+
return null;
726+
});
727+
}
728+
729+
/** @var GroupPluginManager $pluginManager */
730+
$pluginManager = $this->createMock(GroupPluginManager::class);
731+
732+
$ldap = new GroupLDAP($access, $pluginManager);
733+
$resultingMembers = $this->invokePrivate($ldap, '_groupMembers', [$groupDN]);
734+
735+
$expected = array_keys(array_flip($expectedMembers));
736+
737+
$this->assertEquals($expected, array_keys($resultingMembers), '', 0.0, 10, true);
738+
}
656739
}

0 commit comments

Comments
 (0)