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 ], 61*0f498d06SAndreas 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'); 67*0f498d06SAndreas Gohr 68*0f498d06SAndreas Gohr $this->assertGreaterThan(mktime(0,0,0,6,1,2023), $user['lastpwd'], 'lastpwd should be a timestamp'); 69*0f498d06SAndreas 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'); 74*0f498d06SAndreas 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'); 79*0f498d06SAndreas Gohr unset($user['lastpwd']); 8008ace392SAndreas Gohr $this->assertSame($expect, $user); 8108ace392SAndreas Gohr } 8208ace392SAndreas Gohr 8308ace392SAndreas Gohr /** 8408ace392SAndreas Gohr * Check recursive groups 8508ace392SAndreas Gohr * 8608ace392SAndreas Gohr */ 8708ace392SAndreas Gohr public function testGetUserRecursiveGroups() 8808ace392SAndreas Gohr { 8908ace392SAndreas Gohr // User m.albro is member of 'gamma nested', which is in turn part of 'beta' 9008ace392SAndreas Gohr // thus the user should be part of both groups 9108ace392SAndreas Gohr $expect = [ 9208ace392SAndreas Gohr 'beta', 9308ace392SAndreas Gohr 'domain users', 9408ace392SAndreas Gohr 'gamma nested', 9508ace392SAndreas Gohr 'user', 9608ace392SAndreas Gohr ]; 9708ace392SAndreas Gohr 9808ace392SAndreas Gohr $client = $this->getClient(['recursivegroups' => 1]); 9908ace392SAndreas Gohr $user = $client->getUser('m.albro@example.local'); 10008ace392SAndreas Gohr $this->assertSame($expect, $user['grps']); 10108ace392SAndreas Gohr } 10208ace392SAndreas Gohr 10308ace392SAndreas Gohr /** 10408ace392SAndreas Gohr * Check getting all groups 10508ace392SAndreas Gohr */ 10608ace392SAndreas Gohr public function testGetGroups() 10708ace392SAndreas Gohr { 10808ace392SAndreas Gohr // to check paging, we set a super small page size 10908ace392SAndreas Gohr $client = $this->getClient(['page_size' => 2]); 11008ace392SAndreas Gohr 11108ace392SAndreas Gohr $groups = $client->getGroups(); 11208ace392SAndreas Gohr $this->assertGreaterThan(3, count($groups)); 11308ace392SAndreas Gohr $this->assertContains('alpha', $groups); 11408ace392SAndreas Gohr $this->assertContains('beta', $groups); 11508ace392SAndreas Gohr $this->assertContains('gamma nested', $groups); 11608ace392SAndreas Gohr $this->assertContains('domain users', $groups); 11708ace392SAndreas Gohr } 11808ace392SAndreas Gohr 11908ace392SAndreas Gohr /** 12008ace392SAndreas Gohr * Check getting filtered groups 12108ace392SAndreas Gohr */ 12208ace392SAndreas Gohr public function testGetGroupsFiltered() 12308ace392SAndreas Gohr { 12408ace392SAndreas Gohr // to check paging, we set a super small page size 12508ace392SAndreas Gohr $client = $this->getClient(['page_size' => 2]); 12608ace392SAndreas Gohr 12708ace392SAndreas Gohr $groups = $client->getGroups('alpha', ADClient::FILTER_EQUAL); 12808ace392SAndreas Gohr $this->assertCount(1, $groups); 12908ace392SAndreas Gohr $this->assertSame(['alpha'], array_values($groups)); 13008ace392SAndreas Gohr } 13108ace392SAndreas Gohr 13208ace392SAndreas Gohr public function testGetFilteredUsers() 13308ace392SAndreas Gohr { 13408ace392SAndreas Gohr // to check paging, we set a super small page size 13508ace392SAndreas Gohr $client = $this->getClient(['page_size' => 2]); 13608ace392SAndreas Gohr 13708ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'alpha'], ADClient::FILTER_EQUAL); 13808ace392SAndreas Gohr $this->assertGreaterThan(20, count($users)); 13908ace392SAndreas Gohr $this->assertLessThan(150, count($users)); 14008ace392SAndreas Gohr 14108ace392SAndreas Gohr $this->assertArrayHasKey('a.blaskett', $users, 'This user should be in alpha'); 14208ace392SAndreas Gohr $this->assertArrayNotHasKey('a.legrand', $users, 'This user is not in alpha'); 14308ace392SAndreas Gohr 14408ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'alpha', 'name' => 'Andras'], ADClient::FILTER_STARTSWITH); 14508ace392SAndreas Gohr $this->assertCount(1, $users); 14608ace392SAndreas Gohr 14708ace392SAndreas Gohr // a group with a space 14808ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'gamma nested'], ADClient::FILTER_EQUAL); 14908ace392SAndreas Gohr $this->assertArrayHasKey('m.mcnevin', $users, 'This user should be in Gamma Nested'); 15008ace392SAndreas Gohr } 15108ace392SAndreas Gohr 15208ace392SAndreas Gohr public function testGetFilteredUsersRecursiveGroups() 15308ace392SAndreas Gohr { 15408ace392SAndreas Gohr // User m.albro is member of 'gamma nested', which is in turn part of 'beta' 15508ace392SAndreas Gohr // thus the user should be part of both groups 15608ace392SAndreas Gohr 15708ace392SAndreas Gohr $client = $this->getClient(['recursivegroups' => 1]); 15808ace392SAndreas Gohr 15908ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'beta'], ADClient::FILTER_EQUAL); 16008ace392SAndreas Gohr $this->assertArrayHasKey('m.albro', $users, 'user should be in beta'); 16108ace392SAndreas Gohr 16208ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'gamma nested'], ADClient::FILTER_EQUAL); 16308ace392SAndreas Gohr $this->assertArrayHasKey('m.albro', $users, 'user should be in gamma nested'); 16408ace392SAndreas Gohr } 16508ace392SAndreas Gohr 16608ace392SAndreas Gohr public function testGetDomainUsers() 16708ace392SAndreas Gohr { 16808ace392SAndreas Gohr $client = $this->getClient(); 16908ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'domain users'], ADClient::FILTER_EQUAL); 17008ace392SAndreas Gohr $this->assertGreaterThan(250, count($users)); 17108ace392SAndreas Gohr 17208ace392SAndreas Gohr $users = $client->getFilteredUsers(['grps' => 'domain'], ADClient::FILTER_STARTSWITH); 17308ace392SAndreas Gohr $this->assertGreaterThan(250, count($users)); 17408ace392SAndreas Gohr } 17508ace392SAndreas Gohr 17608ace392SAndreas Gohr public function testSetPassword() 17708ace392SAndreas Gohr { 17808ace392SAndreas Gohr $client = $this->getClient(); 17908ace392SAndreas Gohr // password is set as administrator 18008ace392SAndreas Gohr $this->assertTrue($client->setPassword('x.guiu', 'Shibol eTH876?!'), 'Password set as admin'); 18108ace392SAndreas Gohr 18208ace392SAndreas Gohr // login as user 18308ace392SAndreas Gohr $this->assertTrue($client->authenticate('x.guiu', 'Shibol eTH876?!'), 'Password works'); 18408ace392SAndreas Gohr 18508ace392SAndreas Gohr // set new pass as user 18608ace392SAndreas Gohr $this->assertTrue($client->setPassword('x.guiu', 'Fully New 1234??', 'Shibol eTH876?!'), 'Password as user'); 18708ace392SAndreas Gohr 18808ace392SAndreas Gohr // login as user with new password 18908ace392SAndreas Gohr $this->assertTrue($client->authenticate('x.guiu', 'Fully New 1234??'), 'New Password works'); 19008ace392SAndreas Gohr 19108ace392SAndreas Gohr // use new client for admin connection, and reset password back 19208ace392SAndreas Gohr $client = $this->getClient(); 19308ace392SAndreas Gohr $this->assertTrue($client->setPassword('x.guiu', 'Foo_b_ar123!'), 'Password set back as admin'); 19408ace392SAndreas Gohr } 19508ace392SAndreas Gohr 196*0f498d06SAndreas Gohr public function testMaxPasswordAge() 197*0f498d06SAndreas Gohr { 198*0f498d06SAndreas Gohr $client = $this->getClient(); 199*0f498d06SAndreas Gohr $maxAge = $client->getMaxPasswordAge(false); 200*0f498d06SAndreas Gohr 201*0f498d06SAndreas Gohr // convert to days 202*0f498d06SAndreas Gohr $maxAge = $maxAge / 60 / 60 / 24; 203*0f498d06SAndreas Gohr 204*0f498d06SAndreas Gohr $this->assertEquals(42, $maxAge, 'Default password age is 42 days'); 205*0f498d06SAndreas Gohr } 206*0f498d06SAndreas Gohr 20708ace392SAndreas Gohr /** 20808ace392SAndreas Gohr * Check that we can resolve nested groups (users are checked in @see test_getUserRecursiveGroups already) 20908ace392SAndreas Gohr */ 21008ace392SAndreas Gohr// public function test_resolveRecursiveMembership() { 21108ace392SAndreas Gohr// $client = $this->getClient(); 21208ace392SAndreas Gohr// 21308ace392SAndreas Gohr// /** @var \FreeDSx\Ldap\Search\Paging $result */ 21408ace392SAndreas Gohr// $result = $this->callInaccessibleMethod( 21508ace392SAndreas Gohr// $client, 21608ace392SAndreas Gohr// 'resolveRecursiveMembership', 21708ace392SAndreas Gohr// [['CN=beta,CN=Users,DC=example,DC=local'], 'memberOf'] 21808ace392SAndreas Gohr// ); 21908ace392SAndreas Gohr// $entries = $result->getEntries(); 22008ace392SAndreas Gohr// $this->assertEquals(1, $entries->count()); 22108ace392SAndreas Gohr// $this->assertEquals('Gamma Nested', ($entries->first()->get('name')->getValues())[0]); 22208ace392SAndreas Gohr// } 22308ace392SAndreas Gohr} 224