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