xref: /dokuwiki/_test/tests/Remote/ApiCoreAclCheckTest.php (revision 7ec464d90fb88e69d3690d59f84747bc52480fa6)
1<?php
2
3namespace dokuwiki\test\Remote;
4
5use dokuwiki\Remote\AccessDeniedException;
6use dokuwiki\Remote\Api;
7
8/**
9 * Class remoteapicore_test
10 */
11class ApiCoreAclCheckTest extends \DokuWikiTest {
12
13    protected $userinfo;
14    protected $oldAuthAcl;
15    /** @var  Api */
16    protected $remote;
17
18    protected $pluginsEnabled = array('auth_plugin_authplain');
19
20    protected function reloadUsers() {
21        global $auth;
22
23        /* auth caches data loaded from file, but recreated object forces reload */
24        $auth = new \auth_plugin_authplain();
25    }
26
27    public function setUp() : void {
28        global $config_cascade;
29        global $conf;
30        global $USERINFO;
31        global $AUTH_ACL;
32
33        parent::setUp();
34
35        $name = $config_cascade['plainauth.users']['default'];
36        copy($name, $name . ".orig");
37        $this->reloadUsers();
38
39        $this->oldAuthAcl = $AUTH_ACL;
40        $this->userinfo = $USERINFO;
41
42        $conf['remote'] = 1;
43        $conf['remoteuser'] = '@user';
44        $conf['useacl'] = 0;
45
46        $this->remote = new Api();
47
48    }
49
50    public function tearDown() : void {
51        global $USERINFO;
52        global $AUTH_ACL;
53        global $config_cascade;
54
55        parent::tearDown();
56
57        $USERINFO = $this->userinfo;
58        $AUTH_ACL = $this->oldAuthAcl;
59
60        $name = $config_cascade['plainauth.users']['default'];
61        copy($name . ".orig", $name);
62    }
63
64    /**
65     * A regular (non-admin) user may check their own permissions.
66     */
67    public function testCheckaclSelf() {
68        global $conf;
69        global $AUTH_ACL, $USERINFO;
70
71        $conf['useacl'] = 1;
72        $_SERVER['REMOTE_USER'] = 'john';
73        $USERINFO['grps'] = ['user'];
74        $AUTH_ACL = [
75            '*                  @ALL           0', //none
76            '*                  @user          2', //edit
77        ];
78
79        // no user given -> current user is used
80        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', ['nice_page']));
81
82        // naming yourself explicitly is allowed too
83        $params = [
84            'nice_page',
85            'john',
86            ['user']
87        ];
88        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params));
89    }
90
91    /**
92     * On a case-insensitive backend a user may check their own permissions even
93     * when naming themselves in a different case than their logged-in name.
94     */
95    public function testCheckaclSelfCaseInsensitiveBackend() {
96        global $conf;
97        global $AUTH_ACL, $USERINFO;
98        global $auth;
99
100        // logging in as "john" and naming "John" refer to the same user here
101        $auth = new class extends \auth_plugin_authplain {
102            public function isCaseSensitive() {
103                return false;
104            }
105        };
106
107        $conf['useacl'] = 1;
108        $_SERVER['REMOTE_USER'] = 'john';
109        $USERINFO['grps'] = ['user'];
110        $AUTH_ACL = [
111            '*                  @ALL           0', //none
112            '*                  @user          2', //edit
113        ];
114
115        // naming yourself in a different case must not be treated as another user
116        $params = [
117            'nice_page',
118            'John',
119            ['user']
120        ];
121        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params));
122    }
123
124    /**
125     * Checking another user's permissions is restricted to superusers and must
126     * be denied for a regular user.
127     */
128    public function testCheckaclOtherUserDeniedForNonAdmin() {
129        global $conf;
130        global $AUTH_ACL, $USERINFO;
131
132        $conf['useacl'] = 1;
133        $_SERVER['REMOTE_USER'] = 'john';
134        $USERINFO['grps'] = ['user'];
135        $AUTH_ACL = [
136            '*                  @ALL           0', //none
137            '*                  @user          2', //edit
138        ];
139
140        $this->expectException(AccessDeniedException::class);
141        $this->remote->call('core.aclCheck', ['nice_page', 'someoneelse', ['user']]);
142    }
143
144    /**
145     * A superuser may check the permissions of arbitrary users and groups.
146     */
147    public function testCheckaclOtherUsersAsAdmin() {
148        global $conf;
149        global $AUTH_ACL, $USERINFO;
150        /** @var auth_plugin_authplain $auth */
151        global $auth;
152
153        $conf['useacl'] = 1;
154        $_SERVER['REMOTE_USER'] = 'testuser'; // configured superuser, see _test/conf/local.php
155        $USERINFO['grps'] = ['user'];
156        $AUTH_ACL = [
157            '*                  @ALL           0', //none
158            '*                  @user          2', //edit
159            '*                  @more          4', //create
160            'nice_page          user2          8'  //upload
161        ];
162
163        $auth->createUser("user1", "54321", "a User", "you@example.com");
164        $auth->createUser("user2", "543210", "You", "he@example.com");
165        $auth->createUser("mwuser", "12345", "Wiki User", "me@example.com", ['more']); //not in default group
166
167        $params = [
168            'nice_page',
169            'user1'
170        ];
171        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params));
172
173        $params = [
174            'nice_page',
175            'mwuser',
176            // member of group 'more' (automatically retrieved)
177        ];
178        $this->assertEquals(AUTH_CREATE, $this->remote->call('core.aclCheck', $params));
179
180        $params = [
181            'nice_page',
182            'mwuser',
183            [] // member of group 'more' (automatically retrieved)
184        ];
185        $this->assertEquals(AUTH_CREATE, $this->remote->call('core.aclCheck', $params));
186
187        $params = [
188            'nice_page',
189            'notexistinguser',
190            ['more']
191        ];
192        $this->assertEquals(AUTH_CREATE, $this->remote->call('core.aclCheck', $params));
193
194        $params = [
195            'nice_page',
196            'user2',
197            // (automatically retrieved)
198        ];
199        $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', $params));
200
201        $params = [
202            'nice_page',
203            'user2',
204            [] // (automatically retrieved)
205        ];
206        $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', $params));
207
208        $params = [
209            'unknown_page',
210            'user2',
211            // (automatically retrieved)
212        ];
213        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params));
214
215        $params = [
216            'unknown_page',
217            'user2',
218            [] // (automatically retrieved)
219        ];
220        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params));
221
222        $params = array(
223            'nice_page',
224            'testuser', // superuser set via conf
225            // (automatically retrieved)
226        );
227        $this->assertEquals(AUTH_ADMIN, $this->remote->call('core.aclCheck', $params));
228    }
229
230}
231