MDL-37467 Do not provide blog posts via RSS when blogging is disabled
[moodle.git] / auth / db / tests / db_test.php
CommitLineData
e7aeaa65
PS
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/**
18 * External database auth sync tests, this also tests adodb drivers
19 * that are matching our four supported Moodle database drivers.
20 *
21 * @package auth_db
22 * @category phpunit
23 * @copyright 2012 Petr Skoda {@link http://skodak.org}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29
30class auth_db_testcase extends advanced_testcase {
31
32 protected function init_auth_database() {
33 global $DB, $CFG;
34 require_once("$CFG->dirroot/auth/db/auth.php");
35
36 $dbman = $DB->get_manager();
37
38 set_config('extencoding', 'utf-8', 'auth/db');
39
40 set_config('host', $CFG->dbhost, 'auth/db');
41 set_config('user', $CFG->dbuser, 'auth/db');
42 set_config('pass', $CFG->dbpass, 'auth/db');
43 set_config('name', $CFG->dbname, 'auth/db');
44
45 if (!empty($CFG->dboptions['dbport'])) {
46 set_config('host', $CFG->dbhost.':'.$CFG->dboptions['dbport'], 'auth/db');
47 }
48
49 switch (get_class($DB)) {
50 case 'mssql_native_moodle_database':
51 set_config('type', 'mssql_n', 'auth/db');
52 set_config('sybasequoting', '1', 'auth/db');
53 break;
54
55 case 'mysqli_native_moodle_database':
56 set_config('type', 'mysqli', 'auth/db');
57 set_config('setupsql', "SET NAMES 'UTF-8'", 'auth/db');
58 set_config('sybasequoting', '0', 'auth/db');
59 if (!empty($CFG->dboptions['dbsocket'])) {
60 $dbsocket = $CFG->dboptions['dbsocket'];
61 if ((strpos($dbsocket, '/') === false and strpos($dbsocket, '\\') === false)) {
62 $dbsocket = ini_get('mysqli.default_socket');
63 }
64 set_config('type', 'mysqli://'.rawurlencode($CFG->dbuser).':'.rawurlencode($CFG->dbpass).'@'.rawurlencode($CFG->dbhost).'/'.rawurlencode($CFG->dbname).'?socket='.rawurlencode($dbsocket), 'auth/db');
65 }
66 break;
67
68 case 'oci_native_moodle_database':
69 set_config('type', 'oci8po', 'auth/db');
70 set_config('sybasequoting', '1', 'auth/db');
71 break;
72
73 case 'pgsql_native_moodle_database':
74 set_config('type', 'postgres7', 'auth/db');
75 set_config('setupsql', "SET NAMES 'UTF-8'", 'auth/db');
76 set_config('sybasequoting', '0', 'auth/db');
77 if (!empty($CFG->dboptions['dbsocket']) and ($CFG->dbhost === 'localhost' or $CFG->dbhost === '127.0.0.1')) {
78 if (strpos($CFG->dboptions['dbsocket'], '/') !== false) {
79 set_config('host', $CFG->dboptions['dbsocket'], 'auth/db');
80 } else {
81 set_config('host', '', 'auth/db');
82 }
83 }
84 break;
85
86 case 'sqlsrv_native_moodle_database':
87 set_config('type', 'mssqlnative', 'auth/db');
88 set_config('sybasequoting', '1', 'auth/db');
89 break;
90
91 default:
92 throw new exception('Unknown database driver '.get_class($DB));
93 }
94
95 $table = new xmldb_table('auth_db_users');
96 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
97 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null);
98 $table->add_field('pass', XMLDB_TYPE_CHAR, '255', null, null, null);
99 $table->add_field('email', XMLDB_TYPE_CHAR, '255', null, null, null);
100 $table->add_field('firstname', XMLDB_TYPE_CHAR, '255', null, null, null);
101 $table->add_field('lastname', XMLDB_TYPE_CHAR, '255', null, null, null);
102 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
103 if ($dbman->table_exists($table)) {
104 $dbman->drop_table($table);
105 }
106 $dbman->create_table($table);
59706ff6
PS
107 if (!empty($CFG->dboptions['dbschema'])) {
108 set_config('table', $CFG->dboptions['dbschema'].'.'.$CFG->prefix.'auth_db_users', 'auth/db');
109 } else {
110 set_config('table', $CFG->prefix.'auth_db_users', 'auth/db');
111 }
e7aeaa65
PS
112 set_config('fielduser', 'name', 'auth/db');
113 set_config('fieldpass', 'pass', 'auth/db');
114
115 // Setu up field mappings.
116
117 set_config('field_map_email', 'email', 'auth/db');
118 set_config('field_updatelocal_email', 'oncreate', 'auth/db');
119 set_config('field_updateremote_email', '0', 'auth/db');
120 set_config('field_lock_email', 'unlocked', 'auth/db');
121
122 // Init the rest of settings.
123 set_config('passtype', 'plaintext', 'auth/db');
124 set_config('changepasswordurl', '', 'auth/db');
125 set_config('debugauthdb', 0, 'auth/db');
126 set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/db');
127 }
128
129 protected function cleanup_auth_database() {
130 global $DB;
131
132 $dbman = $DB->get_manager();
133 $table = new xmldb_table('auth_db_users');
134 $dbman->drop_table($table);
135 }
136
137 public function test_plugin() {
138 global $DB, $CFG;
139
140 $this->resetAfterTest(false);
141
142 // NOTE: It is strongly discouraged to create new tables in advanced_testcase classes,
143 // but there is no other simple way to test ext database enrol sync, so let's
144 // disable transactions are try to cleanup after the tests.
145
146 $this->preventResetByRollback();
147
148 $this->init_auth_database();
149
150 /** @var auth_plugin_db $auth */
151 $auth = get_auth_plugin('db');
152
153 $authdb = $auth->db_init();
154
155
156 // Test adodb may access the table.
157
158 $user1 = (object)array('name'=>'u1', 'pass'=>'heslo', 'email'=>'u1@example.com');
159 $user1->id = $DB->insert_record('auth_db_users', $user1);
160
161
162 $sql = "SELECT * FROM {$auth->config->table}";
163 $rs = $authdb->Execute($sql);
164 $this->assertInstanceOf('ADORecordSet', $rs);
165 $this->assertFalse($rs->EOF);
166 $fields = $rs->FetchRow();
167 $this->assertTrue(is_array($fields));
168 $this->assertTrue($rs->EOF);
169 $rs->Close();
170
171 $authdb->Close();
172
173
174 // Test bulk user account creation.
175
176 $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
177 $user2->id = $DB->insert_record('auth_db_users', $user2);
178
179 $user3 = (object)array('name'=>'admin', 'pass'=>'heslo', 'email'=>'admin@example.com'); // Should be skipped.
180 $user3->id = $DB->insert_record('auth_db_users', $user3);
181
182 $this->assertCount(2, $DB->get_records('user'));
183
184 $trace = new null_progress_trace();
185 $auth->sync_users($trace, false);
186
187 $this->assertEquals(4, $DB->count_records('user'));
188 $u1 = $DB->get_record('user', array('username'=>$user1->name, 'auth'=>'db'));
189 $this->assertSame($user1->email, $u1->email);
190 $u2 = $DB->get_record('user', array('username'=>$user2->name, 'auth'=>'db'));
191 $this->assertSame($user2->email, $u2->email);
192 $admin = $DB->get_record('user', array('username'=>'admin', 'auth'=>'manual'));
193 $this->assertNotEmpty($admin);
194
195
196 // Test sync updates.
197
198 $user2b = clone($user2);
199 $user2b->email = 'u2b@example.com';
200 $DB->update_record('auth_db_users', $user2b);
201
202 $auth->sync_users($trace, false);
203 $this->assertEquals(4, $DB->count_records('user'));
204 $u2 = $DB->get_record('user', array('username'=>$user2->name));
205 $this->assertSame($user2->email, $u2->email);
206
207 $auth->sync_users($trace, true);
208 $this->assertEquals(4, $DB->count_records('user'));
209 $u2 = $DB->get_record('user', array('username'=>$user2->name));
210 $this->assertSame($user2->email, $u2->email);
211
212 set_config('field_updatelocal_email', 'onlogin', 'auth/db');
213 $auth->config->field_updatelocal_email = 'onlogin';
214
215 $auth->sync_users($trace, false);
216 $this->assertEquals(4, $DB->count_records('user'));
217 $u2 = $DB->get_record('user', array('username'=>$user2->name));
218 $this->assertSame($user2->email, $u2->email);
219
220 $auth->sync_users($trace, true);
221 $this->assertEquals(4, $DB->count_records('user'));
222 $u2 = $DB->get_record('user', array('username'=>$user2->name));
223 $this->assertSame($user2b->email, $u2->email);
224
225
226 // Test sync deletes and suspends.
227
228 $DB->delete_records('auth_db_users', array('id'=>$user2->id));
229 $this->assertCount(2, $DB->get_records('auth_db_users'));
230 unset($user2);
231 unset($user2b);
232
233 $auth->sync_users($trace, false);
234 $this->assertEquals(4, $DB->count_records('user'));
235 $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
236 $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
237
238 set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db');
239 $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
240
241 $auth->sync_users($trace, false);
242 $this->assertEquals(4, $DB->count_records('user'));
243 $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
244 $this->assertEquals(1, $DB->count_records('user', array('suspended'=>1)));
245
246 $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
247 $user2->id = $DB->insert_record('auth_db_users', $user2);
248
249 $auth->sync_users($trace, false);
250 $this->assertEquals(4, $DB->count_records('user'));
251 $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
252 $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
253
254 $DB->delete_records('auth_db_users', array('id'=>$user2->id));
255
256 set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth/db');
257 $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
258
259 $auth->sync_users($trace, false);
260 $this->assertEquals(4, $DB->count_records('user'));
261 $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
262 $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
263
264 $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
265 $user2->id = $DB->insert_record('auth_db_users', $user2);
266
267 $auth->sync_users($trace, false);
268 $this->assertEquals(5, $DB->count_records('user'));
269 $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
270 $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
271
272
273 // Test user_login().
274
275 $user3 = (object)array('name'=>'u3', 'pass'=>'heslo', 'email'=>'u3@example.com');
276 $user3->id = $DB->insert_record('auth_db_users', $user3);
277
278 $this->assertFalse($auth->user_login('u4', 'heslo'));
279 $this->assertTrue($auth->user_login('u1', 'heslo'));
280
281 $this->assertFalse($DB->record_exists('user', array('username'=>'u3', 'auth'=>'db')));
282 $this->assertTrue($auth->user_login('u3', 'heslo'));
283 $this->assertFalse($DB->record_exists('user', array('username'=>'u3', 'auth'=>'db')));
284
285 set_config('passtype', 'md5', 'auth/db');
286 $auth->config->passtype = 'md5';
287 $user3->pass = md5('heslo');
288 $DB->update_record('auth_db_users', $user3);
289 $this->assertTrue($auth->user_login('u3', 'heslo'));
290
291 set_config('passtype', 'sh1', 'auth/db');
292 $auth->config->passtype = 'sha1';
293 $user3->pass = sha1('heslo');
294 $DB->update_record('auth_db_users', $user3);
295 $this->assertTrue($auth->user_login('u3', 'heslo'));
296
297 set_config('passtype', 'internal', 'auth/db');
298 $auth->config->passtype = 'internal';
299 create_user_record('u3', 'heslo', 'db');
300 $this->assertTrue($auth->user_login('u3', 'heslo'));
301
302
303 $DB->delete_records('auth_db_users', array('id'=>$user3->id));
304
305 set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/db');
306 $auth->config->removeuser = AUTH_REMOVEUSER_KEEP;
307 $this->assertTrue($auth->user_login('u3', 'heslo'));
308
309 set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db');
310 $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
311 $this->assertFalse($auth->user_login('u3', 'heslo'));
312
313 set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth/db');
314 $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
315 $this->assertFalse($auth->user_login('u3', 'heslo'));
316
317 set_config('passtype', 'sh1', 'auth/db');
318 $auth->config->passtype = 'sha1';
319 $this->assertFalse($auth->user_login('u3', 'heslo'));
320
321
322 // Test login create and update.
323
324 $user4 = (object)array('name'=>'u4', 'pass'=>'heslo', 'email'=>'u4@example.com');
325 $user4->id = $DB->insert_record('auth_db_users', $user4);
326
327 set_config('passtype', 'plaintext', 'auth/db');
328 $auth->config->passtype = 'plaintext';
329
330 $iuser4 = create_user_record('u4', 'heslo', 'db');
331 $this->assertNotEmpty($iuser4);
332 $this->assertSame($user4->name, $iuser4->username);
333 $this->assertSame($user4->email, $iuser4->email);
334 $this->assertSame('db', $iuser4->auth);
335 $this->assertSame($CFG->mnet_localhost_id, $iuser4->mnethostid);
336
337 $user4b = clone($user4);
338 $user4b->email = 'u4b@example.com';
339 $DB->update_record('auth_db_users', $user4b);
340
341 set_config('field_updatelocal_email', 'oncreate', 'auth/db');
342 $auth->config->field_updatelocal_email = 'oncreate';
343
344 update_user_record('u4');
345 $iuser4 = $DB->get_record('user', array('id'=>$iuser4->id));
346 $this->assertSame($user4->email, $iuser4->email);
347
348 set_config('field_updatelocal_email', 'onlogin', 'auth/db');
349 $auth->config->field_updatelocal_email = 'onlogin';
350
351 update_user_record('u4');
352 $iuser4 = $DB->get_record('user', array('id'=>$iuser4->id));
353 $this->assertSame($user4b->email, $iuser4->email);
354
355
356 // Test user_exists()
357
358 $this->assertTrue($auth->user_exists('u1'));
359 $this->assertTrue($auth->user_exists('admin'));
360 $this->assertFalse($auth->user_exists('u3'));
361 $this->assertTrue($auth->user_exists('u4'));
362
363 $this->cleanup_auth_database();
364 }
365}