xref: /plugin/pureldap/_test/ADClientTest.php (revision 9bafffea15cbe74b15e43cf6bb87ec8340d9eccd)
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