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_db;
18
 
19
/**
20
 * External database auth sync tests, this also tests adodb drivers
21
 * that are matching our four supported Moodle database drivers.
22
 *
23
 * @package    auth_db
24
 * @category   phpunit
25
 * @copyright  2012 Petr Skoda {@link http://skodak.org}
26
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27
 */
28
class db_test extends \advanced_testcase {
29
    /** @var string Original error log */
30
    protected $oldlog;
31
 
32
    /** @var int The amount of users to create for the large user set deletion test  */
33
    protected $largedeletionsetsize = 128;
34
 
35
    public static function tearDownAfterClass(): void {
36
        global $DB;
37
        // Apply sqlsrv native driver error and logging default
38
        // settings while finishing the AdoDB tests.
39
        if ($DB->get_dbfamily() === 'mssql') {
40
            sqlsrv_configure("WarningsReturnAsErrors", false);
41
            sqlsrv_configure("LogSubsystems", SQLSRV_LOG_SYSTEM_OFF);
42
            sqlsrv_configure("LogSeverity", SQLSRV_LOG_SEVERITY_ERROR);
43
        }
44
    }
45
 
46
    protected function init_auth_database() {
47
        global $DB, $CFG;
48
        require_once("$CFG->dirroot/auth/db/auth.php");
49
 
50
        // Discard error logs from AdoDB.
51
        $this->oldlog = ini_get('error_log');
52
        ini_set('error_log', "$CFG->dataroot/testlog.log");
53
 
54
        $dbman = $DB->get_manager();
55
 
56
        set_config('extencoding', 'utf-8', 'auth_db');
57
 
58
        set_config('host', $CFG->dbhost, 'auth_db');
59
        set_config('user', $CFG->dbuser, 'auth_db');
60
        set_config('pass', $CFG->dbpass, 'auth_db');
61
        set_config('name', $CFG->dbname, 'auth_db');
62
 
63
        if (!empty($CFG->dboptions['dbport'])) {
64
            set_config('host', $CFG->dbhost.':'.$CFG->dboptions['dbport'], 'auth_db');
65
        }
66
 
67
        switch ($DB->get_dbfamily()) {
68
 
69
            case 'mysql':
70
                set_config('type', 'mysqli', 'auth_db');
71
                set_config('setupsql', "SET NAMES 'UTF-8'", 'auth_db');
72
                set_config('sybasequoting', '0', 'auth_db');
73
                if (!empty($CFG->dboptions['dbsocket'])) {
74
                    $dbsocket = $CFG->dboptions['dbsocket'];
75
                    if ((strpos($dbsocket, '/') === false and strpos($dbsocket, '\\') === false)) {
76
                        $dbsocket = ini_get('mysqli.default_socket');
77
                    }
78
                    set_config('type', 'mysqli://'.rawurlencode($CFG->dbuser).':'.rawurlencode($CFG->dbpass).'@'.rawurlencode($CFG->dbhost).'/'.rawurlencode($CFG->dbname).'?socket='.rawurlencode($dbsocket), 'auth_db');
79
                }
80
                break;
81
 
82
            case 'oracle':
83
                set_config('type', 'oci8po', 'auth_db');
84
                set_config('sybasequoting', '1', 'auth_db');
85
                break;
86
 
87
            case 'postgres':
88
                set_config('type', 'postgres7', 'auth_db');
89
                $setupsql = "SET NAMES 'UTF-8'";
90
                if (!empty($CFG->dboptions['dbschema'])) {
91
                    $setupsql .= "; SET search_path = '".$CFG->dboptions['dbschema']."'";
92
                }
93
                set_config('setupsql', $setupsql, 'auth_db');
94
                set_config('sybasequoting', '0', 'auth_db');
95
                if (!empty($CFG->dboptions['dbsocket']) and ($CFG->dbhost === 'localhost' or $CFG->dbhost === '127.0.0.1')) {
96
                    if (strpos($CFG->dboptions['dbsocket'], '/') !== false) {
97
                        $socket = $CFG->dboptions['dbsocket'];
98
                        if (!empty($CFG->dboptions['dbport'])) {
99
                            $socket .= ':' . $CFG->dboptions['dbport'];
100
                        }
101
                        set_config('host', $socket, 'auth_db');
102
                    } else {
103
                        set_config('host', '', 'auth_db');
104
                    }
105
                }
106
                break;
107
 
108
            case 'mssql':
109
                set_config('type', 'mssqlnative', 'auth_db');
110
                set_config('sybasequoting', '1', 'auth_db');
111
 
112
                // The native sqlsrv driver uses a comma as separator between host and port.
113
                $dbhost = $CFG->dbhost;
114
                if (!empty($dboptions['dbport'])) {
115
                    $dbhost .= ',' . $dboptions['dbport'];
116
                }
117
                set_config('host', $dbhost, 'auth_db');
118
                break;
119
 
120
            default:
121
                throw new exception('Unknown database family ' . $DB->get_dbfamily());
122
        }
123
 
124
        $table = new \xmldb_table('auth_db_users');
125
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
126
        $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null);
127
        $table->add_field('pass', XMLDB_TYPE_CHAR, '255', null, null, null);
128
        $table->add_field('email', XMLDB_TYPE_CHAR, '255', null, null, null);
129
        $table->add_field('firstname', XMLDB_TYPE_CHAR, '255', null, null, null);
130
        $table->add_field('lastname', XMLDB_TYPE_CHAR, '255', null, null, null);
131
        $table->add_field('animal', XMLDB_TYPE_CHAR, '255', null, null, null);
132
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
133
        if ($dbman->table_exists($table)) {
134
            $dbman->drop_table($table);
135
        }
136
        $dbman->create_table($table);
137
        set_config('table', $CFG->prefix.'auth_db_users', 'auth_db');
138
        set_config('fielduser', 'name', 'auth_db');
139
        set_config('fieldpass', 'pass', 'auth_db');
140
        set_config('field_map_lastname', 'lastname', 'auth_db');
141
        set_config('field_updatelocal_lastname', 'oncreate', 'auth_db');
142
        set_config('field_lock_lastname', 'unlocked', 'auth_db');
143
        // Setu up field mappings.
144
 
145
        set_config('field_map_email', 'email', 'auth_db');
146
        set_config('field_updatelocal_email', 'oncreate', 'auth_db');
147
        set_config('field_updateremote_email', '0', 'auth_db');
148
        set_config('field_lock_email', 'unlocked', 'auth_db');
149
 
150
        // Create a user profile field and add mapping to it.
151
        $this->getDataGenerator()->create_custom_profile_field(['shortname' => 'pet', 'name' => 'Pet', 'datatype' => 'text']);
152
 
153
        set_config('field_map_profile_field_pet', 'animal', 'auth_db');
154
        set_config('field_updatelocal_profile_field_pet', 'oncreate', 'auth_db');
155
        set_config('field_updateremote_profile_field_pet', '0', 'auth_db');
156
        set_config('field_lock_profile_field_pet', 'unlocked', 'auth_db');
157
 
158
        // Init the rest of settings.
159
        set_config('passtype', 'plaintext', 'auth_db');
160
        set_config('changepasswordurl', '', 'auth_db');
161
        set_config('debugauthdb', 0, 'auth_db');
162
        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth_db');
163
    }
164
 
165
    protected function cleanup_auth_database() {
166
        global $DB;
167
 
168
        $dbman = $DB->get_manager();
169
        $table = new \xmldb_table('auth_db_users');
170
        $dbman->drop_table($table);
171
 
172
        ini_set('error_log', $this->oldlog);
173
    }
174
 
11 efrain 175
    public function test_plugin(): void {
1 efrain 176
        global $DB, $CFG;
177
        require_once($CFG->dirroot . '/user/profile/lib.php');
178
 
179
        $this->resetAfterTest(true);
180
 
181
        // NOTE: It is strongly discouraged to create new tables in advanced_testcase classes,
182
        //       but there is no other simple way to test ext database enrol sync, so let's
183
        //       disable transactions are try to cleanup after the tests.
184
 
185
        $this->preventResetByRollback();
186
 
187
        $this->init_auth_database();
188
 
189
        /** @var auth_plugin_db $auth */
190
        $auth = get_auth_plugin('db');
191
 
192
        $authdb = $auth->db_init();
193
 
194
 
195
        // Test adodb may access the table.
196
 
197
        $user1 = (object)array('name'=>'u1', 'pass'=>'heslo', 'email'=>'u1@example.com');
198
        $user1->id = $DB->insert_record('auth_db_users', $user1);
199
 
200
 
201
        $sql = "SELECT * FROM {$auth->config->table}";
202
        $rs = $authdb->Execute($sql);
203
        $this->assertInstanceOf('ADORecordSet', $rs);
204
        $this->assertFalse($rs->EOF);
205
        $fields = $rs->FetchRow();
206
        $this->assertTrue(is_array($fields));
207
        $this->assertTrue($rs->EOF);
208
        $rs->Close();
209
 
210
        $authdb->Close();
211
 
212
 
213
        // Test bulk user account creation.
214
 
215
        $user2 = (object)['name' => 'u2', 'pass' => 'heslo', 'email' => 'u2@example.com', 'animal' => 'cat'];
216
        $user2->id = $DB->insert_record('auth_db_users', $user2);
217
 
218
        $user3 = (object)array('name'=>'admin', 'pass'=>'heslo', 'email'=>'admin@example.com'); // Should be skipped.
219
        $user3->id = $DB->insert_record('auth_db_users', $user3);
220
 
221
        $this->assertCount(2, $DB->get_records('user'));
222
 
223
        $trace = new \null_progress_trace();
224
 
225
        // Sync users and make sure that two events user_created werer triggered.
226
        $sink = $this->redirectEvents();
227
        $auth->sync_users($trace, false);
228
        $events = $sink->get_events();
229
        $sink->close();
230
        $this->assertCount(2, $events);
231
        $this->assertTrue($events[0] instanceof  \core\event\user_created);
232
        $this->assertTrue($events[1] instanceof  \core\event\user_created);
233
 
234
        // Assert the two users were created.
235
        $this->assertEquals(4, $DB->count_records('user'));
236
        $u1 = $DB->get_record('user', array('username'=>$user1->name, 'auth'=>'db'));
237
        $this->assertSame($user1->email, $u1->email);
238
        $this->assertEmpty(profile_user_record($u1->id)->pet);
239
        $u2 = $DB->get_record('user', array('username'=>$user2->name, 'auth'=>'db'));
240
        $this->assertSame($user2->email, $u2->email);
241
        $this->assertSame($user2->animal, profile_user_record($u2->id)->pet);
242
        $admin = $DB->get_record('user', array('username'=>'admin', 'auth'=>'manual'));
243
        $this->assertNotEmpty($admin);
244
 
245
 
246
        // Test sync updates.
247
 
248
        $user2b = clone($user2);
249
        $user2b->email = 'u2b@example.com';
250
        $user2b->animal = 'dog';
251
        $DB->update_record('auth_db_users', $user2b);
252
 
253
        $auth->sync_users($trace, false);
254
        $this->assertEquals(4, $DB->count_records('user'));
255
        $u2 = $DB->get_record('user', array('username'=>$user2->name));
256
        $this->assertSame($user2->email, $u2->email);
257
        $this->assertSame($user2->animal, profile_user_record($u2->id)->pet);
258
 
259
        $auth->sync_users($trace, true);
260
        $this->assertEquals(4, $DB->count_records('user'));
261
        $u2 = $DB->get_record('user', array('username'=>$user2->name));
262
        $this->assertSame($user2->email, $u2->email);
263
 
264
        set_config('field_updatelocal_email', 'onlogin', 'auth_db');
265
        $auth->config->field_updatelocal_email = 'onlogin';
266
        set_config('field_updatelocal_profile_field_pet', 'onlogin', 'auth_db');
267
        $auth->config->field_updatelocal_profile_field_pet = 'onlogin';
268
 
269
        $auth->sync_users($trace, false);
270
        $this->assertEquals(4, $DB->count_records('user'));
271
        $u2 = $DB->get_record('user', array('username'=>$user2->name));
272
        $this->assertSame($user2->email, $u2->email);
273
 
274
        $auth->sync_users($trace, true);
275
        $this->assertEquals(4, $DB->count_records('user'));
276
        $u2 = $DB->get_record('user', array('username'=>$user2->name));
277
        $this->assertSame($user2b->email, $u2->email);
278
        $this->assertSame($user2b->animal, profile_user_record($u2->id)->pet);
279
 
280
 
281
        // Test sync deletes and suspends.
282
 
283
        $DB->delete_records('auth_db_users', array('id'=>$user2->id));
284
        $this->assertCount(2, $DB->get_records('auth_db_users'));
285
        unset($user2);
286
        unset($user2b);
287
 
288
        $auth->sync_users($trace, false);
289
        $this->assertEquals(4, $DB->count_records('user'));
290
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
291
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
292
 
293
        set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth_db');
294
        $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
295
 
296
        $auth->sync_users($trace, false);
297
        $this->assertEquals(4, $DB->count_records('user'));
298
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
299
        $this->assertEquals(1, $DB->count_records('user', array('suspended'=>1)));
300
 
301
        $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
302
        $user2->id = $DB->insert_record('auth_db_users', $user2);
303
 
304
        $auth->sync_users($trace, false);
305
        $this->assertEquals(4, $DB->count_records('user'));
306
        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
307
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
308
 
309
        $DB->delete_records('auth_db_users', array('id'=>$user2->id));
310
 
311
        set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth_db');
312
        $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
313
 
314
        $auth->sync_users($trace, false);
315
        $this->assertEquals(4, $DB->count_records('user'));
316
        $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
317
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
318
 
319
        $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
320
        $user2->id = $DB->insert_record('auth_db_users', $user2);
321
 
322
        $auth->sync_users($trace, false);
323
        $this->assertEquals(5, $DB->count_records('user'));
324
        $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
325
        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
326
 
327
 
328
        // Test user_login().
329
 
330
        $user3 = (object)array('name'=>'u3', 'pass'=>'heslo', 'email'=>'u3@example.com');
331
        $user3->id = $DB->insert_record('auth_db_users', $user3);
332
 
333
        $this->assertFalse($auth->user_login('u4', 'heslo'));
334
        $this->assertTrue($auth->user_login('u1', 'heslo'));
335
 
336
        $this->assertFalse($DB->record_exists('user', array('username'=>'u3', 'auth'=>'db')));
337
        $this->assertTrue($auth->user_login('u3', 'heslo'));
338
        $this->assertFalse($DB->record_exists('user', array('username'=>'u3', 'auth'=>'db')));
339
 
340
        set_config('passtype', 'md5', 'auth_db');
341
        $auth->config->passtype = 'md5';
342
        $user3->pass = md5('heslo');
343
        $DB->update_record('auth_db_users', $user3);
344
        $this->assertTrue($auth->user_login('u3', 'heslo'));
345
 
346
        // Test user created to see if the checking happens strictly.
347
        $usermd5 = (object)['name' => 'usermd5', 'pass' => '0e462097431906509019562988736854'];
348
        $usermd5->id = $DB->insert_record('auth_db_users', $usermd5);
349
 
350
        // md5('240610708') === '0e462097431906509019562988736854'.
351
        $this->assertTrue($auth->user_login('usermd5', '240610708'));
352
        $this->assertFalse($auth->user_login('usermd5', 'QNKCDZO'));
353
 
354
        set_config('passtype', 'sh1', 'auth_db');
355
        $auth->config->passtype = 'sha1';
356
        $user3->pass = sha1('heslo');
357
        $DB->update_record('auth_db_users', $user3);
358
        $this->assertTrue($auth->user_login('u3', 'heslo'));
359
 
360
        // Test user created to see if the checking happens strictly.
361
        $usersha1 = (object)['name' => 'usersha1', 'pass' => '0e66507019969427134894567494305185566735'];
362
        $usersha1->id = $DB->insert_record('auth_db_users', $usersha1);
363
 
364
        // sha1('aaroZmOk') === '0e66507019969427134894567494305185566735'.
365
        $this->assertTrue($auth->user_login('usersha1', 'aaroZmOk'));
366
        $this->assertFalse($auth->user_login('usersha1', 'aaK1STfY'));
367
 
368
        set_config('passtype', 'saltedcrypt', 'auth_db');
369
        $auth->config->passtype = 'saltedcrypt';
370
        $user3->pass = password_hash('heslo', PASSWORD_BCRYPT);
371
        $DB->update_record('auth_db_users', $user3);
372
        $this->assertTrue($auth->user_login('u3', 'heslo'));
373
 
374
        set_config('passtype', 'internal', 'auth_db');
375
        $auth->config->passtype = 'internal';
376
        create_user_record('u3', 'heslo', 'db');
377
        $this->assertTrue($auth->user_login('u3', 'heslo'));
378
 
379
 
380
        $DB->delete_records('auth_db_users', array('id'=>$user3->id));
381
 
382
        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth_db');
383
        $auth->config->removeuser = AUTH_REMOVEUSER_KEEP;
384
        $this->assertTrue($auth->user_login('u3', 'heslo'));
385
 
386
        set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth_db');
387
        $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
388
        $this->assertFalse($auth->user_login('u3', 'heslo'));
389
 
390
        set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth_db');
391
        $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
392
        $this->assertFalse($auth->user_login('u3', 'heslo'));
393
 
394
        set_config('passtype', 'sh1', 'auth_db');
395
        $auth->config->passtype = 'sha1';
396
        $this->assertFalse($auth->user_login('u3', 'heslo'));
397
 
398
 
399
        // Test login create and update.
400
 
401
        $user4 = (object)array('name'=>'u4', 'pass'=>'heslo', 'email'=>'u4@example.com');
402
        $user4->id = $DB->insert_record('auth_db_users', $user4);
403
 
404
        set_config('passtype', 'plaintext', 'auth_db');
405
        $auth->config->passtype = 'plaintext';
406
 
407
        $iuser4 = create_user_record('u4', 'heslo', 'db');
408
        $this->assertNotEmpty($iuser4);
409
        $this->assertSame($user4->name, $iuser4->username);
410
        $this->assertSame($user4->email, $iuser4->email);
411
        $this->assertSame('db', $iuser4->auth);
412
        $this->assertSame($CFG->mnet_localhost_id, $iuser4->mnethostid);
413
 
414
        $user4b = clone($user4);
415
        $user4b->email = 'u4b@example.com';
416
        $DB->update_record('auth_db_users', $user4b);
417
 
418
        set_config('field_updatelocal_email', 'oncreate', 'auth_db');
419
        $auth->config->field_updatelocal_email = 'oncreate';
420
 
421
        update_user_record('u4');
422
        $iuser4 = $DB->get_record('user', array('id'=>$iuser4->id));
423
        $this->assertSame($user4->email, $iuser4->email);
424
 
425
        set_config('field_updatelocal_email', 'onlogin', 'auth_db');
426
        $auth->config->field_updatelocal_email = 'onlogin';
427
 
428
        update_user_record('u4');
429
        $iuser4 = $DB->get_record('user', array('id'=>$iuser4->id));
430
        $this->assertSame($user4b->email, $iuser4->email);
431
 
432
 
433
        // Test user_exists()
434
 
435
        $this->assertTrue($auth->user_exists('u1'));
436
        $this->assertTrue($auth->user_exists('admin'));
437
        $this->assertFalse($auth->user_exists('u3'));
438
        $this->assertTrue($auth->user_exists('u4'));
439
 
440
        $this->cleanup_auth_database();
441
    }
442
 
443
    /**
444
     * Testing the function _colonscope() from ADOdb.
445
     */
11 efrain 446
    public function test_adodb_colonscope(): void {
1 efrain 447
        global $CFG;
448
        require_once($CFG->libdir.'/adodb/adodb.inc.php');
449
        require_once($CFG->libdir.'/adodb/drivers/adodb-odbc.inc.php');
450
        require_once($CFG->libdir.'/adodb/drivers/adodb-db2ora.inc.php');
451
 
452
        $this->resetAfterTest(false);
453
 
454
        $sql = "select * from table WHERE column=:1 AND anothercolumn > :0";
455
        $arr = array('b', 1);
456
        list($sqlout, $arrout) = _colonscope($sql,$arr);
457
        $this->assertEquals("select * from table WHERE column=? AND anothercolumn > ?", $sqlout);
458
        $this->assertEquals(array(1, 'b'), $arrout);
459
    }
460
 
461
    /**
462
     * Testing the clean_data() method.
463
     */
11 efrain 464
    public function test_clean_data(): void {
1 efrain 465
        global $DB;
466
 
467
        $this->resetAfterTest(false);
468
        $this->preventResetByRollback();
469
        $this->init_auth_database();
470
        $auth = get_auth_plugin('db');
471
        $auth->db_init();
472
 
473
        // Create users on external table.
474
        $extdbuser1 = (object)array('name'=>'u1', 'pass'=>'heslo', 'email'=>'u1@example.com');
475
        $extdbuser1->id = $DB->insert_record('auth_db_users', $extdbuser1);
476
 
477
        // User with malicious data on the name (won't be imported).
478
        $extdbuser2 = (object)array('name'=>'user<script>alert(1);</script>xss', 'pass'=>'heslo', 'email'=>'xssuser@example.com');
479
        $extdbuser2->id = $DB->insert_record('auth_db_users', $extdbuser2);
480
 
481
        $extdbuser3 = (object)array('name'=>'u3', 'pass'=>'heslo', 'email'=>'u3@example.com',
482
                'lastname' => 'user<script>alert(1);</script>xss');
483
        $extdbuser3->id = $DB->insert_record('auth_db_users', $extdbuser3);
484
        $trace = new \null_progress_trace();
485
 
486
        // Let's test user sync make sure still works as expected..
487
        $auth->sync_users($trace, true);
488
        $this->assertDebuggingCalled("The property 'lastname' has invalid data and has been cleaned.");
489
        // User with correct data, should be equal to external db.
490
        $user1 = $DB->get_record('user', array('email'=> $extdbuser1->email, 'auth'=>'db'));
491
        $this->assertEquals($extdbuser1->name, $user1->username);
492
        $this->assertEquals($extdbuser1->email, $user1->email);
493
 
494
        // Get the user on moodle user table.
495
        $user2 = $DB->get_record('user', array('email'=> $extdbuser2->email, 'auth'=>'db'));
496
        $user3 = $DB->get_record('user', array('email'=> $extdbuser3->email, 'auth'=>'db'));
497
 
498
        $this->assertEmpty($user2);
499
        $this->assertEquals($extdbuser3->name, $user3->username);
500
        $this->assertEquals('useralert(1);xss', $user3->lastname);
501
 
502
        $this->cleanup_auth_database();
503
    }
504
 
505
    /**
506
     * Testing the deletion of a user when there are many users in the external DB.
507
     */
11 efrain 508
    public function test_deleting_with_many_users(): void {
1 efrain 509
        global $DB;
510
 
511
        $this->resetAfterTest(true);
512
        $this->preventResetByRollback();
513
        $this->init_auth_database();
514
        $auth = get_auth_plugin('db');
515
        $auth->db_init();
516
 
517
        // Set to delete from moodle when missing from DB.
518
        set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth_db');
519
        $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
520
 
521
        // Create users.
522
        $users = [];
523
        for ($i = 0; $i < $this->largedeletionsetsize; $i++) {
524
            $user = (object)array('username' => "u$i", 'name' => "u$i", 'pass' => 'heslo', 'email' => "u$i@example.com");
525
            $user->id  = $DB->insert_record('auth_db_users', $user);
526
            $users[] = $user;
527
        }
528
 
529
        // Sync to moodle.
530
        $trace = new \null_progress_trace();
531
        $auth->sync_users($trace, true);
532
 
533
        // Check user is there.
534
        $user = array_shift($users);
535
        $moodleuser = $DB->get_record('user', array('email' => $user->email, 'auth' => 'db'));
536
        $this->assertNotNull($moodleuser);
537
        $this->assertEquals($user->username, $moodleuser->username);
538
 
539
        // Delete a user.
540
        $DB->delete_records('auth_db_users', array('id' => $user->id));
541
 
542
        // Sync again.
543
        $auth->sync_users($trace, true);
544
 
545
        // Check user is no longer there.
546
        $moodleuser = $DB->get_record('user', array('id' => $moodleuser->id));
547
        $this->assertFalse($auth->user_login($user->username, 'heslo'));
548
        $this->assertEquals(1, $moodleuser->deleted);
549
 
550
        // Make sure it was the only user deleted.
551
        $numberdeleted = $DB->count_records('user', array('deleted' => 1, 'auth' => 'db'));
552
        $this->assertEquals(1, $numberdeleted);
553
 
554
        $this->cleanup_auth_database();
555
    }
556
}