108ace392SAndreas Gohr<?php 208ace392SAndreas Gohr 308ace392SAndreas Gohrnamespace dokuwiki\plugin\pureldap\test; 408ace392SAndreas Gohr 508ace392SAndreas Gohruse dokuwiki\plugin\pureldap\classes\ADClient; 608ace392SAndreas Gohr 708ace392SAndreas Gohr/** 808ace392SAndreas Gohr * General tests for the pureldap plugin 908ace392SAndreas Gohr * 1008ace392SAndreas Gohr * @group plugin_pureldap 1108ace392SAndreas Gohr * @group plugins 1208ace392SAndreas Gohr */ 1308ace392SAndreas Gohrclass ADClientTest extends \DokuWikiTest 1408ace392SAndreas Gohr{ 1508ace392SAndreas Gohr /** 1608ace392SAndreas Gohr * Create a client with default settings 1708ace392SAndreas Gohr * 1808ace392SAndreas Gohr * Optionally allows to override configs. 1908ace392SAndreas Gohr * 2008ace392SAndreas Gohr * All tests assume to be running against https://github.com/splitbrain/vagrant-active-directory 2108ace392SAndreas Gohr * 2208ace392SAndreas Gohr * @param array $conf 2308ace392SAndreas Gohr * @return ADClient 2408ace392SAndreas Gohr */ 2508ace392SAndreas Gohr protected function getClient($conf = []) 2608ace392SAndreas Gohr { 2708ace392SAndreas Gohr return new ADClient( 2808ace392SAndreas Gohr array_merge( 2908ace392SAndreas Gohr [ 3008ace392SAndreas Gohr 'base_dn' => 'DC=example,DC=local', 3108ace392SAndreas Gohr 'suffix' => 'example.local', 3208ace392SAndreas Gohr 'servers' => ['localhost'], 3308ace392SAndreas Gohr 'port' => 7389, // SSL: 7636 3408ace392SAndreas Gohr 'admin_username' => 'vagrant', 3508ace392SAndreas Gohr 'admin_password' => 'vagrant', 3608ace392SAndreas Gohr 'encryption' => 'tls', 3708ace392SAndreas Gohr 'validate' => 'self', 3808ace392SAndreas Gohr 'attributes' => ['mobile'], 3908ace392SAndreas Gohr ], 4008ace392SAndreas Gohr $conf 4108ace392SAndreas Gohr ) 4208ace392SAndreas Gohr ); 4308ace392SAndreas Gohr } 4408ace392SAndreas Gohr 4508ace392SAndreas Gohr /** 4608ace392SAndreas Gohr * Check user fetching 4708ace392SAndreas Gohr */ 4808ace392SAndreas Gohr public function testGetUser() 4908ace392SAndreas Gohr { 5008ace392SAndreas Gohr $expect = [ 5108ace392SAndreas Gohr 'user' => 'a.legrand', 5208ace392SAndreas Gohr 'name' => 'Amerigo Legrand', 5308ace392SAndreas Gohr 'mail' => 'a.legrand@example.com', 5408ace392SAndreas Gohr 'dn' => 'CN=Amerigo Legrand,CN=Users,DC=example,DC=local', 5508ace392SAndreas Gohr 'grps' => [ 5608ace392SAndreas Gohr 'beta', 5708ace392SAndreas Gohr 'domain users', 5808ace392SAndreas Gohr 'gamma nested', 5908ace392SAndreas Gohr 'user', 6008ace392SAndreas Gohr ], 610f498d06SAndreas Gohr 'expires' => false, 6208ace392SAndreas Gohr 'mobile' => '+63 (483) 526-8809', 6308ace392SAndreas Gohr ]; 6408ace392SAndreas Gohr 6508ace392SAndreas Gohr $client = $this->getClient(); 6608ace392SAndreas Gohr $user = $client->getUser('a.legrand@example.local'); 670f498d06SAndreas Gohr 680f498d06SAndreas Gohr $this->assertGreaterThan(mktime(0,0,0,6,1,2023), $user['lastpwd'], 'lastpwd should be a timestamp'); 690f498d06SAndreas Gohr unset($user['lastpwd']); // we don't know the exact value, so we remove it for the comparison 7008ace392SAndreas Gohr $this->assertSame($expect, $user); 7108ace392SAndreas Gohr 7208ace392SAndreas Gohr // access should work without the domain, too 7308ace392SAndreas Gohr $user = $client->getUser('a.legrand'); 740f498d06SAndreas Gohr unset($user['lastpwd']); 7508ace392SAndreas Gohr $this->assertSame($expect, $user); 7608ace392SAndreas Gohr 7708ace392SAndreas Gohr // access should be case Insensitive 7808ace392SAndreas Gohr $user = $client->getUser('A.LeGrand'); 790f498d06SAndreas Gohr unset($user['lastpwd']); 8008ace392SAndreas Gohr $this->assertSame($expect, $user); 8108ace392SAndreas Gohr } 8208ace392SAndreas Gohr 83*9bafffeaSAndreas Gohr public function testGetLongUser() 84*9bafffeaSAndreas Gohr { 85*9bafffeaSAndreas Gohr $client = $this->getClient(); 86*9bafffeaSAndreas Gohr $user = $client->getUser('averylongusernamethatisverylong'); 87*9bafffeaSAndreas Gohr $this->assertIsArray($user); 88*9bafffeaSAndreas Gohr $this->assertEquals('averylongusernamethatisverylong', $user['user']); 89*9bafffeaSAndreas Gohr 90*9bafffeaSAndreas Gohr 91*9bafffeaSAndreas Gohr } 92*9bafffeaSAndreas Gohr 93*9bafffeaSAndreas Gohr 9408ace392SAndreas Gohr /** 9508ace392SAndreas Gohr * Check recursive groups 9608ace392SAndreas Gohr * 9708ace392SAndreas Gohr */ 9808ace392SAndreas Gohr public function testGetUserRecursiveGroups() 9908ace392SAndreas Gohr { 10008ace392SAndreas Gohr // User m.albro is member of 'gamma nested', which is in turn part of 'beta' 10108ace392SAndreas Gohr // thus the user should be part of both groups 10208ace392SAndreas Gohr $expect = [ 10308ace392SAndreas Gohr 'beta', 10408ace392SAndreas Gohr 'domain users', 10508ace392SAndreas Gohr 'gamma nested', 10608ace392SAndreas Gohr 'user', 10708ace392SAndreas Gohr ]; 10808ace392SAndreas Gohr 10908ace392SAndreas Gohr $client = $this->getClient(['recursivegroups' => 1]); 11008ace392SAndreas Gohr $user = $client->getUser('m.albro@example.local'); 11108ace392SAndreas Gohr $this->assertSame($expect, $user['grps']); 11208ace392SAndreas Gohr } 11308ace392SAndreas Gohr 11408ace392SAndreas Gohr /** 11508ace392SAndreas Gohr * Check getting all groups 11608ace392SAndreas Gohr */ 11708ace392SAndreas Gohr public function testGetGroups() 11808ace392SAndreas Gohr { 11908ace392SAndreas Gohr // to check paging, we set a super small page size 12008ace392SAndreas Gohr $client = $this->getClient(['page_size' => 2]); 12108ace392SAndreas Gohr 12208ace392SAndreas Gohr $groups = $client->getGroups(); 12308ace392SAndreas Gohr $this->assertGreaterThan(3, count($groups)); 12408ace392SAndreas Gohr $this->assertContains('alpha', $groups); 12508ace392SAndreas Gohr $this->assertContains('beta', $groups); 12608ace392SAndreas Gohr $this->assertContains('gamma nested', $groups); 12708ace392SAndreas Gohr $this->assertContains('domain users', $groups); 12808ace392SAndreas Gohr } 12908ace392SAndreas Gohr 13008ace392SAndreas Gohr /** 13108ace392SAndreas Gohr * Check getting filtered groups 13208ace392SAndreas Gohr */ 13308ace392SAndreas Gohr public function testGetGroupsFiltered() 13408ace392SAndreas Gohr { 13508ace392SAndreas Gohr // to check paging, we set a super small page size 13608ace392SAndreas Gohr $client = $this->getClient(['page_size' => 2]); 13708ace392SAndreas Gohr 13808ace392SAndreas Gohr $groups = $client->getGroups('alpha', ADClient::FILTER_EQUAL); 13908ace392SAndreas Gohr $this->assertCount(1, $groups); 14008ace392SAndreas Gohr $this->assertSame(['alpha'], array_values($groups)); 14108ace392SAndreas Gohr } 14208ace392SAndreas Gohr 14308ace392SAndreas Gohr public function testGetFilteredUsers() 14408ace392SAndreas Gohr { 14508ace392SAndreas Gohr // to check paging, we set a super small page size 14608ace392SAndreas Gohr $client = $this->getClient(['page_size' => 2]); 14708ace392SAndreas Gohr 14808ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'alpha'], ADClient::FILTER_EQUAL); 14908ace392SAndreas Gohr $this->assertGreaterThan(20, count($users)); 15008ace392SAndreas Gohr $this->assertLessThan(150, count($users)); 15108ace392SAndreas Gohr 15208ace392SAndreas Gohr $this->assertArrayHasKey('a.blaskett', $users, 'This user should be in alpha'); 15308ace392SAndreas Gohr $this->assertArrayNotHasKey('a.legrand', $users, 'This user is not in alpha'); 15408ace392SAndreas Gohr 15508ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'alpha', 'name' => 'Andras'], ADClient::FILTER_STARTSWITH); 15608ace392SAndreas Gohr $this->assertCount(1, $users); 15708ace392SAndreas Gohr 15808ace392SAndreas Gohr // a group with a space 15908ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'gamma nested'], ADClient::FILTER_EQUAL); 16008ace392SAndreas Gohr $this->assertArrayHasKey('m.mcnevin', $users, 'This user should be in Gamma Nested'); 16108ace392SAndreas Gohr } 16208ace392SAndreas Gohr 16308ace392SAndreas Gohr public function testGetFilteredUsersRecursiveGroups() 16408ace392SAndreas Gohr { 16508ace392SAndreas Gohr // User m.albro is member of 'gamma nested', which is in turn part of 'beta' 16608ace392SAndreas Gohr // thus the user should be part of both groups 16708ace392SAndreas Gohr 16808ace392SAndreas Gohr $client = $this->getClient(['recursivegroups' => 1]); 16908ace392SAndreas Gohr 17008ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'beta'], ADClient::FILTER_EQUAL); 17108ace392SAndreas Gohr $this->assertArrayHasKey('m.albro', $users, 'user should be in beta'); 17208ace392SAndreas Gohr 17308ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'gamma nested'], ADClient::FILTER_EQUAL); 17408ace392SAndreas Gohr $this->assertArrayHasKey('m.albro', $users, 'user should be in gamma nested'); 17508ace392SAndreas Gohr } 17608ace392SAndreas Gohr 17708ace392SAndreas Gohr public function testGetDomainUsers() 17808ace392SAndreas Gohr { 17908ace392SAndreas Gohr $client = $this->getClient(); 18008ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'domain users'], ADClient::FILTER_EQUAL); 18108ace392SAndreas Gohr $this->assertGreaterThan(250, count($users)); 18208ace392SAndreas Gohr 18308ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'domain'], ADClient::FILTER_STARTSWITH); 18408ace392SAndreas Gohr $this->assertGreaterThan(250, count($users)); 18508ace392SAndreas Gohr } 18608ace392SAndreas Gohr 18708ace392SAndreas Gohr public function testSetPassword() 18808ace392SAndreas Gohr { 18908ace392SAndreas Gohr $client = $this->getClient(); 19008ace392SAndreas Gohr // password is set as administrator 19108ace392SAndreas Gohr $this->assertTrue($client->setPassword('x.guiu', 'Shibol eTH876?!'), 'Password set as admin'); 19208ace392SAndreas Gohr 19308ace392SAndreas Gohr // login as user 19408ace392SAndreas Gohr $this->assertTrue($client->authenticate('x.guiu', 'Shibol eTH876?!'), 'Password works'); 19508ace392SAndreas Gohr 19608ace392SAndreas Gohr // set new pass as user 19708ace392SAndreas Gohr $this->assertTrue($client->setPassword('x.guiu', 'Fully New 1234??', 'Shibol eTH876?!'), 'Password as user'); 19808ace392SAndreas Gohr 19908ace392SAndreas Gohr // login as user with new password 20008ace392SAndreas Gohr $this->assertTrue($client->authenticate('x.guiu', 'Fully New 1234??'), 'New Password works'); 20108ace392SAndreas Gohr 20208ace392SAndreas Gohr // use new client for admin connection, and reset password back 20308ace392SAndreas Gohr $client = $this->getClient(); 20408ace392SAndreas Gohr $this->assertTrue($client->setPassword('x.guiu', 'Foo_b_ar123!'), 'Password set back as admin'); 20508ace392SAndreas Gohr } 20608ace392SAndreas Gohr 2070f498d06SAndreas Gohr public function testMaxPasswordAge() 2080f498d06SAndreas Gohr { 2090f498d06SAndreas Gohr $client = $this->getClient(); 2100f498d06SAndreas Gohr $maxAge = $client->getMaxPasswordAge(false); 2110f498d06SAndreas Gohr 2120f498d06SAndreas Gohr // convert to days 2130f498d06SAndreas Gohr $maxAge = $maxAge / 60 / 60 / 24; 2140f498d06SAndreas Gohr 2150f498d06SAndreas Gohr $this->assertEquals(42, $maxAge, 'Default password age is 42 days'); 2160f498d06SAndreas Gohr } 2170f498d06SAndreas Gohr 21808ace392SAndreas Gohr /** 21908ace392SAndreas Gohr * Check that we can resolve nested groups (users are checked in @see test_getUserRecursiveGroups already) 22008ace392SAndreas Gohr */ 22108ace392SAndreas Gohr// public function test_resolveRecursiveMembership() { 22208ace392SAndreas Gohr// $client = $this->getClient(); 22308ace392SAndreas Gohr// 22408ace392SAndreas Gohr// /** @var \FreeDSx\Ldap\Search\Paging $result */ 22508ace392SAndreas Gohr// $result = $this->callInaccessibleMethod( 22608ace392SAndreas Gohr// $client, 22708ace392SAndreas Gohr// 'resolveRecursiveMembership', 22808ace392SAndreas Gohr// [['CN=beta,CN=Users,DC=example,DC=local'], 'memberOf'] 22908ace392SAndreas Gohr// ); 23008ace392SAndreas Gohr// $entries = $result->getEntries(); 23108ace392SAndreas Gohr// $this->assertEquals(1, $entries->count()); 23208ace392SAndreas Gohr// $this->assertEquals('Gamma Nested', ($entries->first()->get('name')->getValues())[0]); 23308ace392SAndreas Gohr// } 23408ace392SAndreas Gohr} 235