From cec8b11c4316733c432d1fb153ecced5b3601205 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Feb 2018 12:04:48 +0100 Subject: [PATCH 1/2] tests for retrieving group members with numerical uids Signed-off-by: Arthur Schiwon --- apps/user_ldap/tests/Group_LDAPTest.php | 85 ++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php index 906db6bb17..150f009e95 100644 --- a/apps/user_ldap/tests/Group_LDAPTest.php +++ b/apps/user_ldap/tests/Group_LDAPTest.php @@ -30,6 +30,7 @@ namespace OCA\User_LDAP\Tests; use OCA\User_LDAP\Group_LDAP as GroupLDAP; use OCA\User_LDAP\ILDAPWrapper; +use Test\TestCase; /** * Class GroupLDAPTest @@ -38,7 +39,7 @@ use OCA\User_LDAP\ILDAPWrapper; * * @package OCA\User_LDAP\Tests */ -class Group_LDAPTest extends \Test\TestCase { +class Group_LDAPTest extends TestCase { private function getAccessMock() { static $conMethods; static $accMethods; @@ -511,4 +512,86 @@ class Group_LDAPTest extends \Test\TestCase { $groupsAgain = $groupBackend->getUserGroups('userX'); $this->assertEquals(['group1', 'group2'], $groupsAgain); } + + public function groupMemberProvider() { + $base = 'dc=species,dc=earth'; + + $groups0 = [ + 'uid=3723,' . $base, + 'uid=8372,' . $base, + 'uid=8427,' . $base, + 'uid=2333,' . $base, + 'uid=4754,' . $base, + ]; + $groups1 = [ + '3723', + '8372', + '8427', + '2333', + '4754', + ]; + $groups2Nested = ['6642', '1424']; + $expGroups2 = array_merge($groups1, $groups2Nested); + + return [ + [ #0 – test DNs + 'cn=Birds,' . $base, + $groups0, + ['cn=Birds,' . $base => $groups0] + ], + [ #1 – test uids + 'cn=Birds,' . $base, + $groups1, + ['cn=Birds,' . $base => $groups1] + ], + [ #2 – test uids with nested groups + 'cn=Birds,' . $base, + $expGroups2, + [ + 'cn=Birds,' . $base => $groups1, + '8427' => $groups2Nested, // simplified - nested groups would work with DNs + ], + ], + ]; + } + + /** + * @param string $groupDN + * @param string[] $expectedMembers + * @param array $groupsInfo + * @dataProvider groupMemberProvider + */ + public function testGroupMembers($groupDN, $expectedMembers, $groupsInfo = null) { + $access = $this->getAccessMock(); + $access->expects($this->any()) + ->method('readAttribute') + ->willReturnCallback(function($group) use ($groupDN, $expectedMembers, $groupsInfo) { + if(isset($groupsInfo[$group])) { + return $groupsInfo[$group]; + } + return []; + }); + + $access->connection = $this->createMock(Connection::class); + if(count($groupsInfo) > 1) { + $access->connection->expects($this->any()) + ->method('__get') + ->willReturnCallback(function($name) { + if($name === 'ldapNestedGroups') { + return 1; + } + return null; + }); + } + + /** @var GroupPluginManager $pluginManager */ + $pluginManager = $this->createMock(GroupPluginManager::class); + + $ldap = new GroupLDAP($access, $pluginManager); + $resultingMembers = $this->invokePrivate($ldap, '_groupMembers', [$groupDN]); + + $expected = array_keys(array_flip($expectedMembers)); + + $this->assertEquals($expected, array_keys($resultingMembers), '', 0.0, 10, true); + } } From 5ddcb173e1a747f1a51295876d437f72200218d4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Feb 2018 12:05:50 +0100 Subject: [PATCH 2/2] fix retrieving group members with numerical uids from LDAP Signed-off-by: Arthur Schiwon --- apps/user_ldap/lib/Group_LDAP.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php index d620a00f84..64c9e9dded 100644 --- a/apps/user_ldap/lib/Group_LDAP.php +++ b/apps/user_ldap/lib/Group_LDAP.php @@ -198,6 +198,7 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface { * @param string $dnGroup * @param array|null &$seen * @return array|mixed|null + * @throws \OC\ServerNotAvailableException */ private function _groupMembers($dnGroup, &$seen = null) { if ($seen === null) { @@ -211,26 +212,26 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface { // used extensively in cron job, caching makes sense for nested groups $cacheKey = '_groupMembers'.$dnGroup; $groupMembers = $this->access->connection->getFromCache($cacheKey); - if(!is_null($groupMembers)) { + if($groupMembers !== null) { return $groupMembers; } $seen[$dnGroup] = 1; $members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr, $this->access->connection->ldapGroupFilter); if (is_array($members)) { - foreach ($members as $memberDN) { - $allMembers[$memberDN] = 1; + foreach ($members as $member) { + $allMembers[$member] = 1; $nestedGroups = $this->access->connection->ldapNestedGroups; if (!empty($nestedGroups)) { - $subMembers = $this->_groupMembers($memberDN, $seen); + $subMembers = $this->_groupMembers($member, $seen); if ($subMembers) { - $allMembers = array_merge($allMembers, $subMembers); + $allMembers += $subMembers; } } } } - $allMembers = array_merge($allMembers, $this->getDynamicGroupMembers($dnGroup)); + $allMembers += $this->getDynamicGroupMembers($dnGroup); $this->access->connection->writeToCache($cacheKey, $allMembers); return $allMembers;