Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace auth_ldap;
18
 
19
/**
20
 * LDAP authentication plugin tests.
21
 *
22
 * NOTE: in order to execute this test you need to set up
23
 *       OpenLDAP server with core, cosine, nis and internet schemas
24
 *       and add configuration constants to config.php or phpunit.xml configuration file:
25
 *
26
 * define('TEST_AUTH_LDAP_HOST_URL', 'ldap://127.0.0.1');
27
 * define('TEST_AUTH_LDAP_BIND_DN', 'cn=someuser,dc=example,dc=local');
28
 * define('TEST_AUTH_LDAP_BIND_PW', 'somepassword');
29
 * define('TEST_AUTH_LDAP_DOMAIN', 'dc=example,dc=local');
30
 *
31
 * @package    auth_ldap
32
 * @copyright  2013 Petr Skoda {@link http://skodak.org}
33
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 */
35
 
36
use auth_plugin_ldap;
37
use auth_ldap\task\{
38
    sync_task,
39
    asynchronous_sync_task,
40
};
41
 
42
/**
43
 * LDAP authentication plugin tests.
44
 *
45
 * @package    auth_ldap
46
 * @copyright  2013 Petr Skoda {@link http://skodak.org}
47
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
48
 */
49
class auth_ldap_test extends \advanced_testcase {
50
 
51
    public static function setUpBeforeClass(): void {
52
        global $CFG;
53
        parent::setUpBeforeClass();
54
 
55
        require_once($CFG->dirroot . '/auth/ldap/auth.php');
56
        require_once($CFG->libdir . '/ldaplib.php');
57
    }
58
 
59
    /**
60
     * Data provider for auth_ldap tests
61
     *
62
     * Used to ensure that all the paged stuff works properly, irrespectively
63
     * of the pagesize configured (that implies all the chunking and paging
64
     * built in the plugis is doing its work consistently). Both searching and
65
     * not searching within subcontexts.
66
     *
67
     * @return array[]
68
     */
69
    public function auth_ldap_provider() {
70
        $pagesizes = [1, 3, 5, 1000];
71
        $subcontexts = [0, 1];
72
        $combinations = [];
73
        foreach ($pagesizes as $pagesize) {
74
            foreach ($subcontexts as $subcontext) {
75
                $combinations["pagesize {$pagesize}, subcontexts {$subcontext}"] = [$pagesize, $subcontext];
76
            }
77
        }
78
        return $combinations;
79
    }
80
 
81
    /**
82
     * General auth_ldap testcase
83
     *
84
     * @dataProvider auth_ldap_provider
85
     * @param int $pagesize Value to be configured in settings controlling page size.
86
     * @param int $subcontext Value to be configured in settings controlling searching in subcontexts.
87
     */
11 efrain 88
    public function test_auth_ldap(int $pagesize, int $subcontext): void {
1 efrain 89
        global $DB;
90
 
91
        if (!extension_loaded('ldap')) {
92
            $this->markTestSkipped('LDAP extension is not loaded.');
93
        }
94
 
95
        $this->resetAfterTest();
96
 
97
        if (!defined('TEST_AUTH_LDAP_HOST_URL') or !defined('TEST_AUTH_LDAP_BIND_DN') or !defined('TEST_AUTH_LDAP_BIND_PW') or !defined('TEST_AUTH_LDAP_DOMAIN')) {
98
            $this->markTestSkipped('External LDAP test server not configured.');
99
        }
100
 
101
        // Make sure we can connect the server.
102
        $debuginfo = '';
103
        if (!$connection = ldap_connect_moodle(TEST_AUTH_LDAP_HOST_URL, 3, 'rfc2307', TEST_AUTH_LDAP_BIND_DN, TEST_AUTH_LDAP_BIND_PW, LDAP_DEREF_NEVER, $debuginfo, false)) {
104
            $this->markTestSkipped('Can not connect to LDAP test server: '.$debuginfo);
105
        }
106
 
107
        $this->enable_plugin();
108
 
109
        // Create new empty test container.
110
        $topdn = 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN;
111
 
112
        $this->recursive_delete($connection, TEST_AUTH_LDAP_DOMAIN, 'dc=moodletest');
113
 
114
        $o = array();
115
        $o['objectClass'] = array('dcObject', 'organizationalUnit');
116
        $o['dc']         = 'moodletest';
117
        $o['ou']         = 'MOODLETEST';
118
        if (!ldap_add($connection, 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN, $o)) {
119
            $this->markTestSkipped('Can not create test LDAP container.');
120
        }
121
 
122
        // Create a few users.
123
        $o = array();
124
        $o['objectClass'] = array('organizationalUnit');
125
        $o['ou']          = 'users';
126
        ldap_add($connection, 'ou='.$o['ou'].','.$topdn, $o);
127
 
128
        $createdusers = array();
129
        for ($i=1; $i<=5; $i++) {
130
            $this->create_ldap_user($connection, $topdn, $i);
131
            $createdusers[] = 'username' . $i;
132
        }
133
 
134
        // Set up creators group.
135
        $assignedroles = array('username1', 'username2');
136
        $o = array();
137
        $o['objectClass'] = array('posixGroup');
138
        $o['cn']          = 'creators';
139
        $o['gidNumber']   = 1;
140
        $o['memberUid']   = $assignedroles;
141
        ldap_add($connection, 'cn='.$o['cn'].','.$topdn, $o);
142
 
143
        $creatorrole = $DB->get_record('role', array('shortname'=>'coursecreator'));
144
        $this->assertNotEmpty($creatorrole);
145
 
146
 
147
        // Configure the plugin a bit.
148
        set_config('host_url', TEST_AUTH_LDAP_HOST_URL, 'auth_ldap');
149
        set_config('start_tls', 0, 'auth_ldap');
150
        set_config('ldap_version', 3, 'auth_ldap');
151
        set_config('ldapencoding', 'utf-8', 'auth_ldap');
152
        set_config('pagesize', $pagesize, 'auth_ldap');
153
        set_config('bind_dn', TEST_AUTH_LDAP_BIND_DN, 'auth_ldap');
154
        set_config('bind_pw', TEST_AUTH_LDAP_BIND_PW, 'auth_ldap');
155
        set_config('user_type', 'rfc2307', 'auth_ldap');
156
        set_config('contexts', 'ou=users,'.$topdn, 'auth_ldap');
157
        set_config('search_sub', $subcontext, 'auth_ldap');
158
        set_config('opt_deref', LDAP_DEREF_NEVER, 'auth_ldap');
159
        set_config('user_attribute', 'cn', 'auth_ldap');
160
        set_config('memberattribute', 'memberuid', 'auth_ldap');
161
        set_config('memberattribute_isdn', 0, 'auth_ldap');
162
        set_config('coursecreatorcontext', 'cn=creators,'.$topdn, 'auth_ldap');
163
        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth_ldap');
164
 
165
        set_config('field_map_email', 'mail', 'auth_ldap');
166
        set_config('field_updatelocal_email', 'oncreate', 'auth_ldap');
167
        set_config('field_updateremote_email', '0', 'auth_ldap');
168
        set_config('field_lock_email', 'unlocked', 'auth_ldap');
169
 
170
        set_config('field_map_firstname', 'givenName', 'auth_ldap');
171
        set_config('field_updatelocal_firstname', 'oncreate', 'auth_ldap');
172
        set_config('field_updateremote_firstname', '0', 'auth_ldap');
173
        set_config('field_lock_firstname', 'unlocked', 'auth_ldap');
174
 
175
        set_config('field_map_lastname', 'sn', 'auth_ldap');
176
        set_config('field_updatelocal_lastname', 'oncreate', 'auth_ldap');
177
        set_config('field_updateremote_lastname', '0', 'auth_ldap');
178
        set_config('field_lock_lastname', 'unlocked', 'auth_ldap');
179
 
180
 
181
        $this->assertEquals(2, $DB->count_records('user'));
182
        $this->assertEquals(0, $DB->count_records('role_assignments'));
183
 
184
        /** @var \auth_plugin_ldap $auth */
185
        $auth = get_auth_plugin('ldap');
186
 
187
        ob_start();
188
        $sink = $this->redirectEvents();
189
        $auth->sync_users(true);
190
        $events = $sink->get_events();
191
        $sink->close();
192
        ob_end_clean();
193
 
194
        // Check events, 5 users created with 2 users having roles.
195
        $this->assertCount(7, $events);
196
        foreach ($events as $index => $event) {
197
            $username = $DB->get_field('user', 'username', array('id' => $event->relateduserid)); // Get username.
198
 
199
            if ($event->eventname === '\core\event\user_created') {
200
                $this->assertContains($username, $createdusers);
201
                unset($events[$index]); // Remove matching event.
202
 
203
            } else if ($event->eventname === '\core\event\role_assigned') {
204
                $this->assertContains($username, $assignedroles);
205
                unset($events[$index]); // Remove matching event.
206
 
207
            } else {
208
                $this->fail('Unexpected event found: ' . $event->eventname);
209
            }
210
        }
211
        // If all the user_created and role_assigned events have matched
212
        // then the $events array should be now empty.
213
        $this->assertCount(0, $events);
214
 
215
        $this->assertEquals(5, $DB->count_records('user', array('auth'=>'ldap')));
216
        $this->assertEquals(2, $DB->count_records('role_assignments'));
217
        $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
218
 
219
        for ($i=1; $i<=5; $i++) {
220
            $this->assertTrue($DB->record_exists('user', array('username'=>'username'.$i, 'email'=>'user'.$i.'@example.com', 'firstname'=>'Firstname'.$i, 'lastname'=>'Lastname'.$i)));
221
        }
222
 
223
        $this->delete_ldap_user($connection, $topdn, 1);
224
 
225
        ob_start();
226
        $sink = $this->redirectEvents();
227
        $auth->sync_users(true);
228
        $events = $sink->get_events();
229
        $sink->close();
230
        ob_end_clean();
231
 
232
        // Check events, no new event.
233
        $this->assertCount(0, $events);
234
 
235
        $this->assertEquals(5, $DB->count_records('user', array('auth'=>'ldap')));
236
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
237
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
238
        $this->assertEquals(2, $DB->count_records('role_assignments'));
239
        $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
240
 
241
 
242
        set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth_ldap');
243
 
244
        /** @var \auth_plugin_ldap $auth */
245
        $auth = get_auth_plugin('ldap');
246
 
247
        ob_start();
248
        $sink = $this->redirectEvents();
249
        $auth->sync_users(true);
250
        $events = $sink->get_events();
251
        $sink->close();
252
        ob_end_clean();
253
 
254
        // Check events, 1 user got updated.
255
        $this->assertCount(1, $events);
256
        $event = reset($events);
257
        $this->assertInstanceOf('\core\event\user_updated', $event);
258
 
259
        $this->assertEquals(5, $DB->count_records('user', array('auth'=>'ldap')));
260
        $this->assertEquals(0, $DB->count_records('user', array('auth'=>'nologin', 'username'=>'username1')));
261
        $this->assertEquals(1, $DB->count_records('user', array('auth'=>'ldap', 'suspended'=>'1', 'username'=>'username1')));
262
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
263
        $this->assertEquals(2, $DB->count_records('role_assignments'));
264
        $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
265
 
266
        $this->create_ldap_user($connection, $topdn, 1);
267
 
268
        ob_start();
269
        $sink = $this->redirectEvents();
270
        $auth->sync_users(true);
271
        $events = $sink->get_events();
272
        $sink->close();
273
        ob_end_clean();
274
 
275
        // Check events, 1 user got updated.
276
        $this->assertCount(1, $events);
277
        $event = reset($events);
278
        $this->assertInstanceOf('\core\event\user_updated', $event);
279
 
280
        $this->assertEquals(5, $DB->count_records('user', array('auth'=>'ldap')));
281
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
282
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
283
        $this->assertEquals(2, $DB->count_records('role_assignments'));
284
        $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
285
 
286
        $DB->set_field('user', 'auth', 'nologin', array('username'=>'username1'));
287
 
288
        ob_start();
289
        $sink = $this->redirectEvents();
290
        $auth->sync_users(true);
291
        $events = $sink->get_events();
292
        $sink->close();
293
        ob_end_clean();
294
 
295
        // Check events, 1 user got updated.
296
        $this->assertCount(1, $events);
297
        $event = reset($events);
298
        $this->assertInstanceOf('\core\event\user_updated', $event);
299
 
300
        $this->assertEquals(5, $DB->count_records('user', array('auth'=>'ldap')));
301
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
302
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
303
        $this->assertEquals(2, $DB->count_records('role_assignments'));
304
        $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
305
 
306
        set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth_ldap');
307
 
308
        /** @var \auth_plugin_ldap $auth */
309
        $auth = get_auth_plugin('ldap');
310
 
311
        $this->delete_ldap_user($connection, $topdn, 1);
312
 
313
        ob_start();
314
        $sink = $this->redirectEvents();
315
        $auth->sync_users(true);
316
        $events = $sink->get_events();
317
        $sink->close();
318
        ob_end_clean();
319
 
320
        // Check events, 2 events role_unassigned and user_deleted.
321
        $this->assertCount(2, $events);
322
        $event = array_pop($events);
323
        $this->assertInstanceOf('\core\event\user_deleted', $event);
324
        $event = array_pop($events);
325
        $this->assertInstanceOf('\core\event\role_unassigned', $event);
326
 
327
        $this->assertEquals(5, $DB->count_records('user', array('auth'=>'ldap')));
328
        $this->assertEquals(0, $DB->count_records('user', array('username'=>'username1')));
329
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
330
        $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
331
        $this->assertEquals(1, $DB->count_records('role_assignments'));
332
        $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
333
 
334
        $this->create_ldap_user($connection, $topdn, 1);
335
 
336
        ob_start();
337
        $sink = $this->redirectEvents();
338
        $auth->sync_users(true);
339
        $events = $sink->get_events();
340
        $sink->close();
341
        ob_end_clean();
342
 
343
        // Check events, 2 events role_assigned and user_created.
344
        $this->assertCount(2, $events);
345
        $event = array_pop($events);
346
        $this->assertInstanceOf('\core\event\role_assigned', $event);
347
        $event = array_pop($events);
348
        $this->assertInstanceOf('\core\event\user_created', $event);
349
 
350
        $this->assertEquals(6, $DB->count_records('user', array('auth'=>'ldap')));
351
        $this->assertEquals(1, $DB->count_records('user', array('username'=>'username1')));
352
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
353
        $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
354
        $this->assertEquals(2, $DB->count_records('role_assignments'));
355
        $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$creatorrole->id)));
356
 
357
        // Let's test syncing users in chunks of '1'.
358
        set_config('field_updatelocal_email', 'onlogin', 'auth_ldap');
359
        set_config('sync_updateuserchunk', 1, 'auth_ldap');
360
 
361
        /** @var auth_plugin_ldap $auth */
362
        $auth = get_auth_plugin('ldap');
363
 
364
        $count = 0;
365
        ob_start();
366
        $auth->sync_users_update_callback(function ($users, $updatekeys) use (&$count) {
367
            $count++;
368
        });
369
        ob_end_clean();
370
        // After updating in chunks of '1', we should have counted more than one update.
371
        $this->assertGreaterThan(1, $count);
372
 
373
        ob_start();
374
        \core\cron::setup_user();
375
        $cron = new sync_task();
376
        $cron->execute();
377
 
378
        $this->runAdhocTasks('\auth_ldap\task\asynchronous_sync_task');
379
        $output = ob_get_contents();
380
        ob_end_clean();
381
 
382
        // Use Reflection to make protected constants available.
383
        $rp = new \ReflectionClassConstant(sync_task::class, 'MTRACE_MSG');
384
        $synctaskmsg = $rp->getValue();
385
        $rp = new \ReflectionClassConstant(asynchronous_sync_task::class, 'MTRACE_MSG');
386
        $asynctaskmsg = $rp->getValue();
387
 
388
        $this->assertMatchesRegularExpression(
389
            sprintf('/%s.*%s/s', $synctaskmsg, $asynctaskmsg),
390
            $output
391
        );
392
 
393
        $this->recursive_delete($connection, TEST_AUTH_LDAP_DOMAIN, 'dc=moodletest');
394
        ldap_close($connection);
395
    }
396
 
397
    /**
398
     * Test logging in via LDAP calls a user_loggedin event.
399
     */
11 efrain 400
    public function test_ldap_user_loggedin_event(): void {
1 efrain 401
        global $CFG, $DB, $USER;
402
 
403
        $this->resetAfterTest();
404
 
405
        $this->assertFalse(isloggedin());
406
        $user = $DB->get_record('user', array('username'=>'admin'));
407
 
408
        // Note: we are just going to trigger the function that calls the event,
409
        // not actually perform a LDAP login, for the sake of sanity.
410
        $ldap = new \auth_plugin_ldap();
411
 
412
        // Set the key for the cache flag we want to set which is used by LDAP.
413
        set_cache_flag($ldap->pluginconfig . '/ntlmsess', sesskey(), $user->username, AUTH_NTLMTIMEOUT);
414
 
415
        // We are going to need to set the sesskey as the user's password in order for the LDAP log in to work.
416
        update_internal_user_password($user, sesskey());
417
 
418
        // The function ntlmsso_finish is responsible for triggering the event, so call it directly and catch the event.
419
        $sink = $this->redirectEvents();
420
        // We need to supress this function call, or else we will get the message "session_regenerate_id(): Cannot
421
        // regenerate session id - headers already sent" as the ntlmsso_finish function calls complete_user_login
422
        @$ldap->ntlmsso_finish();
423
        $events = $sink->get_events();
424
        $sink->close();
425
 
426
        // Check that the event is valid.
427
        $this->assertCount(1, $events);
428
        $event = reset($events);
429
        $this->assertInstanceOf('\core\event\user_loggedin', $event);
430
        $this->assertEquals('user', $event->objecttable);
431
        $this->assertEquals('2', $event->objectid);
432
        $this->assertEquals(\context_system::instance()->id, $event->contextid);
433
    }
434
 
435
    /**
436
     * Test logging in via LDAP calls a user_loggedin event.
437
     */
11 efrain 438
    public function test_ldap_user_signup(): void {
1 efrain 439
        global $CFG, $DB;
440
 
441
        // User to create.
442
        $user = array(
443
            'username' => 'usersignuptest1',
444
            'password' => 'Moodle2014!',
445
            'idnumber' => 'idsignuptest1',
446
            'firstname' => 'First Name User Test 1',
447
            'lastname' => 'Last Name User Test 1',
448
            'middlename' => 'Middle Name User Test 1',
449
            'lastnamephonetic' => '最後のお名前のテスト一号',
450
            'firstnamephonetic' => 'お名前のテスト一号',
451
            'alternatename' => 'Alternate Name User Test 1',
452
            'email' => 'usersignuptest1@example.com',
453
            'description' => 'This is a description for user 1',
454
            'city' => 'Perth',
455
            'country' => 'AU',
456
            'mnethostid' => $CFG->mnet_localhost_id,
457
            'auth' => 'ldap'
458
            );
459
 
460
        if (!extension_loaded('ldap')) {
461
            $this->markTestSkipped('LDAP extension is not loaded.');
462
        }
463
 
464
        $this->resetAfterTest();
465
 
466
        if (!defined('TEST_AUTH_LDAP_HOST_URL') or !defined('TEST_AUTH_LDAP_BIND_DN') or !defined('TEST_AUTH_LDAP_BIND_PW') or !defined('TEST_AUTH_LDAP_DOMAIN')) {
467
            $this->markTestSkipped('External LDAP test server not configured.');
468
        }
469
 
470
        // Make sure we can connect the server.
471
        $debuginfo = '';
472
        if (!$connection = ldap_connect_moodle(TEST_AUTH_LDAP_HOST_URL, 3, 'rfc2307', TEST_AUTH_LDAP_BIND_DN, TEST_AUTH_LDAP_BIND_PW, LDAP_DEREF_NEVER, $debuginfo, false)) {
473
            $this->markTestSkipped('Can not connect to LDAP test server: '.$debuginfo);
474
        }
475
 
476
        $this->enable_plugin();
477
 
478
        // Create new empty test container.
479
        $topdn = 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN;
480
 
481
        $this->recursive_delete($connection, TEST_AUTH_LDAP_DOMAIN, 'dc=moodletest');
482
 
483
        $o = array();
484
        $o['objectClass'] = array('dcObject', 'organizationalUnit');
485
        $o['dc']         = 'moodletest';
486
        $o['ou']         = 'MOODLETEST';
487
        if (!ldap_add($connection, 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN, $o)) {
488
            $this->markTestSkipped('Can not create test LDAP container.');
489
        }
490
 
491
        // Create a few users.
492
        $o = array();
493
        $o['objectClass'] = array('organizationalUnit');
494
        $o['ou']          = 'users';
495
        ldap_add($connection, 'ou='.$o['ou'].','.$topdn, $o);
496
 
497
        // Configure the plugin a bit.
498
        set_config('host_url', TEST_AUTH_LDAP_HOST_URL, 'auth_ldap');
499
        set_config('start_tls', 0, 'auth_ldap');
500
        set_config('ldap_version', 3, 'auth_ldap');
501
        set_config('ldapencoding', 'utf-8', 'auth_ldap');
502
        set_config('pagesize', '2', 'auth_ldap');
503
        set_config('bind_dn', TEST_AUTH_LDAP_BIND_DN, 'auth_ldap');
504
        set_config('bind_pw', TEST_AUTH_LDAP_BIND_PW, 'auth_ldap');
505
        set_config('user_type', 'rfc2307', 'auth_ldap');
506
        set_config('contexts', 'ou=users,'.$topdn, 'auth_ldap');
507
        set_config('search_sub', 0, 'auth_ldap');
508
        set_config('opt_deref', LDAP_DEREF_NEVER, 'auth_ldap');
509
        set_config('user_attribute', 'cn', 'auth_ldap');
510
        set_config('memberattribute', 'memberuid', 'auth_ldap');
511
        set_config('memberattribute_isdn', 0, 'auth_ldap');
512
        set_config('creators', 'cn=creators,'.$topdn, 'auth_ldap');
513
        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth_ldap');
514
 
515
        set_config('field_map_email', 'mail', 'auth_ldap');
516
        set_config('field_updatelocal_email', 'oncreate', 'auth_ldap');
517
        set_config('field_updateremote_email', '0', 'auth_ldap');
518
        set_config('field_lock_email', 'unlocked', 'auth_ldap');
519
 
520
        set_config('field_map_firstname', 'givenName', 'auth_ldap');
521
        set_config('field_updatelocal_firstname', 'oncreate', 'auth_ldap');
522
        set_config('field_updateremote_firstname', '0', 'auth_ldap');
523
        set_config('field_lock_firstname', 'unlocked', 'auth_ldap');
524
 
525
        set_config('field_map_lastname', 'sn', 'auth_ldap');
526
        set_config('field_updatelocal_lastname', 'oncreate', 'auth_ldap');
527
        set_config('field_updateremote_lastname', '0', 'auth_ldap');
528
        set_config('field_lock_lastname', 'unlocked', 'auth_ldap');
529
        set_config('passtype', 'md5', 'auth_ldap');
530
        set_config('create_context', 'ou=users,'.$topdn, 'auth_ldap');
531
 
532
        $this->assertEquals(2, $DB->count_records('user'));
533
        $this->assertEquals(0, $DB->count_records('role_assignments'));
534
 
535
        /** @var \auth_plugin_ldap $auth */
536
        $auth = get_auth_plugin('ldap');
537
 
538
        $sink = $this->redirectEvents();
539
        $mailsink = $this->redirectEmails();
540
        $auth->user_signup((object)$user, false);
541
        $this->assertEquals(1, $mailsink->count());
542
        $events = $sink->get_events();
543
        $sink->close();
544
 
545
        // Verify 2 events get generated.
546
        $this->assertCount(2, $events);
547
 
548
        // Get record from db.
549
        $dbuser = $DB->get_record('user', array('username' => $user['username']));
550
        $user['id'] = $dbuser->id;
551
 
552
        // Last event is user_created.
553
        $event = array_pop($events);
554
        $this->assertInstanceOf('\core\event\user_created', $event);
555
        $this->assertEquals($user['id'], $event->objectid);
556
        $this->assertEquals(\context_user::instance($user['id']), $event->get_context());
557
 
558
        // First event is user_password_updated.
559
        $event = array_pop($events);
560
        $this->assertInstanceOf('\core\event\user_password_updated', $event);
561
        $this->assertEventContextNotUsed($event);
562
 
563
        // Delete user which we just created.
564
        ldap_delete($connection, 'cn='.$user['username'].',ou=users,'.$topdn);
565
    }
566
 
567
    protected function create_ldap_user($connection, $topdn, $i) {
568
        $o = array();
569
        $o['objectClass']   = array('inetOrgPerson', 'organizationalPerson', 'person', 'posixAccount');
570
        $o['cn']            = 'username'.$i;
571
        $o['sn']            = 'Lastname'.$i;
572
        $o['givenName']     = 'Firstname'.$i;
573
        $o['uid']           = $o['cn'];
574
        $o['uidnumber']     = 2000+$i;
575
        $o['gidNumber']     = 1000+$i;
576
        $o['homeDirectory'] = '/';
577
        $o['mail']          = 'user'.$i.'@example.com';
578
        $o['userPassword']  = 'pass'.$i;
579
        ldap_add($connection, 'cn='.$o['cn'].',ou=users,'.$topdn, $o);
580
    }
581
 
582
    protected function delete_ldap_user($connection, $topdn, $i) {
583
        ldap_delete($connection, 'cn=username'.$i.',ou=users,'.$topdn);
584
    }
585
 
586
    protected function enable_plugin() {
587
        $auths = get_enabled_auth_plugins();
588
        if (!in_array('ldap', $auths)) {
589
            $auths[] = 'ldap';
590
 
591
        }
592
        set_config('auth', implode(',', $auths));
593
    }
594
 
595
    protected function recursive_delete($connection, $dn, $filter) {
596
        if ($res = ldap_list($connection, $dn, $filter, array('dn'))) {
597
            $info = ldap_get_entries($connection, $res);
598
            ldap_free_result($res);
599
            if ($info['count'] > 0) {
600
                if ($res = ldap_search($connection, "$filter,$dn", 'cn=*', array('dn'))) {
601
                    $info = ldap_get_entries($connection, $res);
602
                    ldap_free_result($res);
603
                    foreach ($info as $i) {
604
                        if (isset($i['dn'])) {
605
                            ldap_delete($connection, $i['dn']);
606
                        }
607
                    }
608
                }
609
                if ($res = ldap_search($connection, "$filter,$dn", 'ou=*', array('dn'))) {
610
                    $info = ldap_get_entries($connection, $res);
611
                    ldap_free_result($res);
612
                    foreach ($info as $i) {
613
                        if (isset($i['dn']) and $info[0]['dn'] != $i['dn']) {
614
                            ldap_delete($connection, $i['dn']);
615
                        }
616
                    }
617
                }
618
                ldap_delete($connection, "$filter,$dn");
619
            }
620
        }
621
    }
622
}