xref: /plugin/pureldap/_test/ADClientTest.php (revision 9bafffea15cbe74b15e43cf6bb87ec8340d9eccd)
1<?php
2
3namespace dokuwiki\plugin\pureldap\test;
4
5use dokuwiki\plugin\pureldap\classes\ADClient;
6
7/**
8 * General tests for the pureldap plugin
9 *
10 * @group plugin_pureldap
11 * @group plugins
12 */
13class ADClientTest extends \DokuWikiTest
14{
15    /**
16     * Create a client with default settings
17     *
18     * Optionally allows to override configs.
19     *
20     * All tests assume to be running against https://github.com/splitbrain/vagrant-active-directory
21     *
22     * @param array $conf
23     * @return ADClient
24     */
25    protected function getClient($conf = [])
26    {
27        return new ADClient(
28            array_merge(
29                [
30                    'base_dn' => 'DC=example,DC=local',
31                    'suffix' => 'example.local',
32                    'servers' => ['localhost'],
33                    'port' => 7389, // SSL: 7636
34                    'admin_username' => 'vagrant',
35                    'admin_password' => 'vagrant',
36                    'encryption' => 'tls',
37                    'validate' => 'self',
38                    'attributes' => ['mobile'],
39                ],
40                $conf
41            )
42        );
43    }
44
45    /**
46     * Check user fetching
47     */
48    public function testGetUser()
49    {
50        $expect = [
51            'user' => 'a.legrand',
52            'name' => 'Amerigo Legrand',
53            'mail' => 'a.legrand@example.com',
54            'dn' => 'CN=Amerigo Legrand,CN=Users,DC=example,DC=local',
55            'grps' => [
56                'beta',
57                'domain users',
58                'gamma nested',
59                'user',
60            ],
61            'expires' => false,
62            'mobile' => '+63 (483) 526-8809',
63        ];
64
65        $client = $this->getClient();
66        $user = $client->getUser('a.legrand@example.local');
67
68        $this->assertGreaterThan(mktime(0,0,0,6,1,2023), $user['lastpwd'], 'lastpwd should be a timestamp');
69        unset($user['lastpwd']); // we don't know the exact value, so we remove it for the comparison
70        $this->assertSame($expect, $user);
71
72        // access should work without the domain, too
73        $user = $client->getUser('a.legrand');
74        unset($user['lastpwd']);
75        $this->assertSame($expect, $user);
76
77        // access should be case Insensitive
78        $user = $client->getUser('A.LeGrand');
79        unset($user['lastpwd']);
80        $this->assertSame($expect, $user);
81    }
82
83    public function testGetLongUser()
84    {
85        $client = $this->getClient();
86        $user = $client->getUser('averylongusernamethatisverylong');
87        $this->assertIsArray($user);
88        $this->assertEquals('averylongusernamethatisverylong', $user['user']);
89
90
91    }
92
93
94    /**
95     * Check recursive groups
96     *
97     */
98    public function testGetUserRecursiveGroups()
99    {
100        // User m.albro is member of 'gamma nested', which is in turn part of 'beta'
101        // thus the user should be part of both groups
102        $expect = [
103            'beta',
104            'domain users',
105            'gamma nested',
106            'user',
107        ];
108
109        $client = $this->getClient(['recursivegroups' => 1]);
110        $user = $client->getUser('m.albro@example.local');
111        $this->assertSame($expect, $user['grps']);
112    }
113
114    /**
115     * Check getting all groups
116     */
117    public function testGetGroups()
118    {
119        // to check paging, we set a super small page size
120        $client = $this->getClient(['page_size' => 2]);
121
122        $groups = $client->getGroups();
123        $this->assertGreaterThan(3, count($groups));
124        $this->assertContains('alpha', $groups);
125        $this->assertContains('beta', $groups);
126        $this->assertContains('gamma nested', $groups);
127        $this->assertContains('domain users', $groups);
128    }
129
130    /**
131     * Check getting filtered groups
132     */
133    public function testGetGroupsFiltered()
134    {
135        // to check paging, we set a super small page size
136        $client = $this->getClient(['page_size' => 2]);
137
138        $groups = $client->getGroups('alpha', ADClient::FILTER_EQUAL);
139        $this->assertCount(1, $groups);
140        $this->assertSame(['alpha'], array_values($groups));
141    }
142
143    public function testGetFilteredUsers()
144    {
145        // to check paging, we set a super small page size
146        $client = $this->getClient(['page_size' => 2]);
147
148        $users = $client->getFilteredUsers(['grps' => 'alpha'], ADClient::FILTER_EQUAL);
149        $this->assertGreaterThan(20, count($users));
150        $this->assertLessThan(150, count($users));
151
152        $this->assertArrayHasKey('a.blaskett', $users, 'This user should be in alpha');
153        $this->assertArrayNotHasKey('a.legrand', $users, 'This user is not in alpha');
154
155        $users = $client->getFilteredUsers(['grps' => 'alpha', 'name' => 'Andras'], ADClient::FILTER_STARTSWITH);
156        $this->assertCount(1, $users);
157
158        // a group with a space
159        $users = $client->getFilteredUsers(['grps' => 'gamma nested'], ADClient::FILTER_EQUAL);
160        $this->assertArrayHasKey('m.mcnevin', $users, 'This user should be in Gamma Nested');
161    }
162
163    public function testGetFilteredUsersRecursiveGroups()
164    {
165        // User m.albro is member of 'gamma nested', which is in turn part of 'beta'
166        // thus the user should be part of both groups
167
168        $client = $this->getClient(['recursivegroups' => 1]);
169
170        $users = $client->getFilteredUsers(['grps' => 'beta'], ADClient::FILTER_EQUAL);
171        $this->assertArrayHasKey('m.albro', $users, 'user should be in beta');
172
173        $users = $client->getFilteredUsers(['grps' => 'gamma nested'], ADClient::FILTER_EQUAL);
174        $this->assertArrayHasKey('m.albro', $users, 'user should be in gamma nested');
175    }
176
177    public function testGetDomainUsers()
178    {
179        $client = $this->getClient();
180        $users = $client->getFilteredUsers(['grps' => 'domain users'], ADClient::FILTER_EQUAL);
181        $this->assertGreaterThan(250, count($users));
182
183        $users = $client->getFilteredUsers(['grps' => 'domain'], ADClient::FILTER_STARTSWITH);
184        $this->assertGreaterThan(250, count($users));
185    }
186
187    public function testSetPassword()
188    {
189        $client = $this->getClient();
190        // password is set as administrator
191        $this->assertTrue($client->setPassword('x.guiu', 'Shibol eTH876?!'), 'Password set as admin');
192
193        // login as user
194        $this->assertTrue($client->authenticate('x.guiu', 'Shibol eTH876?!'), 'Password works');
195
196        // set new pass as user
197        $this->assertTrue($client->setPassword('x.guiu', 'Fully New 1234??', 'Shibol eTH876?!'), 'Password as user');
198
199        // login as user with new password
200        $this->assertTrue($client->authenticate('x.guiu', 'Fully New 1234??'), 'New Password works');
201
202        // use new client for admin connection, and reset password back
203        $client = $this->getClient();
204        $this->assertTrue($client->setPassword('x.guiu', 'Foo_b_ar123!'), 'Password set back as admin');
205    }
206
207    public function testMaxPasswordAge()
208    {
209        $client = $this->getClient();
210        $maxAge = $client->getMaxPasswordAge(false);
211
212        // convert to days
213        $maxAge = $maxAge / 60 / 60 / 24;
214
215        $this->assertEquals(42, $maxAge, 'Default password age is 42 days');
216    }
217
218    /**
219     * Check that we can resolve nested groups (users are checked in @see test_getUserRecursiveGroups already)
220     */
221//    public function test_resolveRecursiveMembership() {
222//        $client = $this->getClient();
223//
224//        /** @var \FreeDSx\Ldap\Search\Paging $result */
225//        $result = $this->callInaccessibleMethod(
226//            $client,
227//            'resolveRecursiveMembership',
228//            [['CN=beta,CN=Users,DC=example,DC=local'], 'memberOf']
229//        );
230//        $entries = $result->getEntries();
231//        $this->assertEquals(1, $entries->count());
232//        $this->assertEquals('Gamma Nested', ($entries->first()->get('name')->getValues())[0]);
233//    }
234}
235