Proyectos de Subversion Moodle

Rev

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