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