1<?php
2
3/**
4 * Class testable_auth_plugin_authpdo
5 *
6 * makes protected methods public for testing
7 */
8class testable_auth_plugin_authpdo extends auth_plugin_authpdo {
9    public function getPluginName() {
10        return 'authpdo';
11    }
12
13    public function selectGroups() {
14        return parent::selectGroups();
15    }
16
17    public function addGroup($group) {
18        return parent::addGroup($group);
19    }
20}
21
22/**
23 * General tests for the authpdo plugin
24 *
25 * @group plugin_authpdo
26 * @group plugins
27 */
28class sqlite_plugin_authpdo_test extends DokuWikiTest {
29
30    protected $dbfile;
31
32    public function test_pdo_sqlite_support() {
33        if(!class_exists('PDO') || !in_array('sqlite',PDO::getAvailableDrivers())) {
34            $this->markTestSkipped('skipping all authpdo tests for sqlite.  Need PDO_sqlite extension');
35        }
36        $this->assertTrue(true); // avoid being marked as risky for having no assertion
37    }
38
39    public function setUp() : void {
40        parent::setUp();
41        $this->dbfile = tempnam('/tmp/', 'pluginpdo_test_');
42        copy(__DIR__ . '/test.sqlite3', $this->dbfile);
43
44        global $conf;
45
46        $conf['plugin']['authpdo']['debug'] = 1;
47        $conf['plugin']['authpdo']['dsn'] = 'sqlite:' . $this->dbfile;
48        $conf['plugin']['authpdo']['user'] = '';
49        $conf['plugin']['authpdo']['pass'] = '';
50
51        $conf['plugin']['authpdo']['select-user'] = 'SELECT id AS uid, login AS user, name, pass AS clear, mail FROM user WHERE login = :user';
52        $conf['plugin']['authpdo']['select-user-groups'] = 'SELECT * FROM member AS m, "group" AS g  WHERE m.gid = g.id AND  m.uid = :uid';
53        $conf['plugin']['authpdo']['select-groups'] = 'SELECT id AS gid, "group" FROM "group"';
54
55        $conf['plugin']['authpdo']['insert-user'] = 'INSERT INTO user (login, pass, name, mail) VALUES (:user, :hash, :name, :mail)';
56        $conf['plugin']['authpdo']['delete-user'] = 'DELETE FROM user WHERE id = :uid';
57
58        $conf['plugin']['authpdo']['list-users'] = 'SELECT DISTINCT login as user
59                                                      FROM user U, member M, "group" G
60                                                     WHERE U.id = M.uid
61                                                       AND M.gid = G.id
62                                                       AND G."group" LIKE :group
63                                                       AND U.login LIKE :user
64                                                       AND U.name LIKE :name
65                                                       AND U.mail LIKE :mail
66                                                  ORDER BY login
67                                                     LIMIT :start,:limit';
68
69        $conf['plugin']['authpdo']['count-users'] = 'SELECT COUNT(DISTINCT login) as count
70                                                      FROM user U, member M, "group" G
71                                                     WHERE U.id = M.uid
72                                                       AND M.gid = G.id
73                                                       AND G."group" LIKE :group
74                                                       AND U.login LIKE :user
75                                                       AND U.name LIKE :name
76                                                       AND U.mail LIKE :mail';
77
78
79        $conf['plugin']['authpdo']['update-user-login'] = 'UPDATE user SET login = :newlogin WHERE id = :uid';
80        $conf['plugin']['authpdo']['update-user-info'] = 'UPDATE user SET name = :name, mail = :mail WHERE id = :uid';
81        $conf['plugin']['authpdo']['update-user-pass'] = 'UPDATE user SET pass = :hash WHERE id = :uid';
82
83        $conf['plugin']['authpdo']['insert-group'] = 'INSERT INTO "group" ("group") VALUES (:group)';
84        $conf['plugin']['authpdo']['join-group'] = 'INSERT INTO member (uid, gid) VALUES (:uid, :gid)';
85        $conf['plugin']['authpdo']['leave-group'] = 'DELETE FROM member WHERE uid = :uid AND gid = :gid';
86    }
87
88    public function tearDown() : void {
89        parent::tearDown();
90        unlink($this->dbfile);
91    }
92
93    /**
94     * @depends test_pdo_sqlite_support
95     */
96    public function test_internals() {
97        $auth = new testable_auth_plugin_authpdo();
98
99        $groups = $auth->selectGroups();
100        $this->assertArrayHasKey('user', $groups);
101        $this->assertEquals(1, $groups['user']['gid']);
102        $this->assertArrayHasKey('admin', $groups);
103        $this->assertEquals(2, $groups['admin']['gid']);
104
105        $ok = $auth->addGroup('test');
106        $this->assertTrue($ok);
107        $groups = $auth->selectGroups();
108        $this->assertArrayHasKey('test', $groups);
109        $this->assertEquals(4, $groups['test']['gid']);
110    }
111
112    /**
113     * @depends test_pdo_sqlite_support
114     */
115    public function test_userinfo() {
116        global $conf;
117        $auth = new auth_plugin_authpdo();
118
119        // clear text pasword (with default config above
120        $this->assertFalse($auth->checkPass('nobody', 'nope'));
121        $this->assertFalse($auth->checkPass('admin', 'nope'));
122        $this->assertTrue($auth->checkPass('admin', 'password'));
123
124        // now with a hashed password
125        $conf['plugin']['authpdo']['select-user'] = 'SELECT id AS uid, login AS user, name, pass AS hash, mail FROM user WHERE login = :user';
126        $this->assertFalse($auth->checkPass('admin', 'password'));
127        $this->assertFalse($auth->checkPass('user', md5('password')));
128
129        // access user data
130        $info = $auth->getUserData('admin');
131        $this->assertEquals('admin', $info['user']);
132        $this->assertEquals('The Admin', $info['name']);
133        $this->assertEquals('admin@example.com', $info['mail']);
134        $this->assertEquals(array('additional', 'admin', 'user'), $info['grps']);
135
136        // group retrieval
137        $this->assertEquals(array('additional', 'admin', 'user'), $auth->retrieveGroups());
138        $this->assertEquals(array('admin', 'user'), $auth->retrieveGroups(1));
139        $this->assertEquals(array('additional'), $auth->retrieveGroups(0, 1));
140
141        // user creation
142        $auth->createUser('test', 'password', 'A Test user', 'test@example.com', array('newgroup'));
143        $info = $auth->getUserData('test');
144        $this->assertEquals('test', $info['user']);
145        $this->assertEquals('A Test user', $info['name']);
146        $this->assertEquals('test@example.com', $info['mail']);
147        $this->assertEquals(array('newgroup', 'user'), $info['grps']);
148        $this->assertEquals(array('additional', 'admin', 'newgroup', 'user'), $auth->retrieveGroups());
149
150        // user modification
151        $auth->modifyUser('test', array('user' => 'tester', 'name' => 'The Test User', 'pass' => 'secret'));
152        $info = $auth->getUserData('tester');
153        $this->assertEquals('tester', $info['user']);
154        $this->assertEquals('The Test User', $info['name']);
155        $this->assertTrue($auth->checkPass('tester','secret'));
156
157        // move user to different groups
158        $auth->modifyUser('tester', array('grps' => array('user', 'admin', 'another')));
159        $info = $auth->getUserData('tester');
160        $this->assertEquals(array('admin', 'another', 'user'), $info['grps']);
161
162
163        $expect = array(
164            'admin' => array(
165                'user' => 'admin',
166                'name' => 'The Admin',
167                'mail' => 'admin@example.com',
168                'uid' => '1',
169                'grps' => array('additional', 'admin', 'user')
170            ),
171            'user' => array(
172                'user' => 'user',
173                'name' => 'A normal user',
174                'mail' => 'user@example.com',
175                'uid' => '2',
176                'grps' => array('user')
177            ),
178            'tester' => array(
179                'user' => 'tester',
180                'name' => 'The Test User',
181                'mail' => 'test@example.com',
182                'uid' => '3',
183                'grps' => array('admin', 'another', 'user')
184            )
185        );
186
187        // list users
188        $users = $auth->retrieveUsers();
189        $this->assertEquals(array($expect['admin'], $expect['tester'], $expect['user']), $users);
190
191        $users = $auth->retrieveUsers(1); // offset
192        $this->assertEquals(array($expect['tester'], $expect['user']), $users);
193
194        $users = $auth->retrieveUsers(1, 1); // offset + limit
195        $this->assertEquals(array($expect['tester']), $users);
196
197        $users = $auth->retrieveUsers(0, -1, array('group' => 'admin')); // full group
198        $this->assertEquals(array($expect['admin'], $expect['tester']), $users);
199        $count = $auth->getUserCount(array('grps' => 'admin'));
200        $this->assertSame(2, $count);
201
202        $users = $auth->retrieveUsers(0, -1, array('group' => 'dmi')); // substring
203        $this->assertEquals(array($expect['admin'], $expect['tester']), $users);
204        $count = $auth->getUserCount(array('grps' => 'dmi'));
205        $this->assertSame(2, $count);
206
207        $users = $auth->retrieveUsers(0, -1, array('user' => 'dmi')); // substring
208        $this->assertEquals(array($expect['admin']), $users);
209        $count = $auth->getUserCount(array('user' => 'dmi'));
210        $this->assertSame(1, $count);
211
212        // delete user
213        $num = $auth->deleteUsers(array('tester', 'foobar'));
214        $this->assertSame(1, $num);
215
216    }
217
218}
219