1285c73a1SAndreas Gohr<?php 2285c73a1SAndreas Gohr 3285c73a1SAndreas Gohrnamespace dokuwiki\test\Remote; 4285c73a1SAndreas Gohr 5884caed9SAndreas Gohruse dokuwiki\Remote\AccessDeniedException; 6285c73a1SAndreas Gohruse dokuwiki\Remote\Api; 7285c73a1SAndreas Gohr 8285c73a1SAndreas Gohr/** 9285c73a1SAndreas Gohr * Class remoteapicore_test 10285c73a1SAndreas Gohr */ 11285c73a1SAndreas Gohrclass ApiCoreAclCheckTest extends \DokuWikiTest { 12285c73a1SAndreas Gohr 13285c73a1SAndreas Gohr protected $userinfo; 14285c73a1SAndreas Gohr protected $oldAuthAcl; 15285c73a1SAndreas Gohr /** @var Api */ 16285c73a1SAndreas Gohr protected $remote; 17285c73a1SAndreas Gohr 18285c73a1SAndreas Gohr protected $pluginsEnabled = array('auth_plugin_authplain'); 19285c73a1SAndreas Gohr 20285c73a1SAndreas Gohr protected function reloadUsers() { 21285c73a1SAndreas Gohr global $auth; 22285c73a1SAndreas Gohr 23285c73a1SAndreas Gohr /* auth caches data loaded from file, but recreated object forces reload */ 24285c73a1SAndreas Gohr $auth = new \auth_plugin_authplain(); 25285c73a1SAndreas Gohr } 26285c73a1SAndreas Gohr 27285c73a1SAndreas Gohr public function setUp() : void { 28285c73a1SAndreas Gohr global $config_cascade; 29285c73a1SAndreas Gohr global $conf; 30285c73a1SAndreas Gohr global $USERINFO; 31285c73a1SAndreas Gohr global $AUTH_ACL; 32285c73a1SAndreas Gohr 33285c73a1SAndreas Gohr parent::setUp(); 34285c73a1SAndreas Gohr 35285c73a1SAndreas Gohr $name = $config_cascade['plainauth.users']['default']; 36285c73a1SAndreas Gohr copy($name, $name . ".orig"); 37285c73a1SAndreas Gohr $this->reloadUsers(); 38285c73a1SAndreas Gohr 39285c73a1SAndreas Gohr $this->oldAuthAcl = $AUTH_ACL; 40285c73a1SAndreas Gohr $this->userinfo = $USERINFO; 41285c73a1SAndreas Gohr 42285c73a1SAndreas Gohr $conf['remote'] = 1; 43285c73a1SAndreas Gohr $conf['remoteuser'] = '@user'; 44285c73a1SAndreas Gohr $conf['useacl'] = 0; 45285c73a1SAndreas Gohr 46285c73a1SAndreas Gohr $this->remote = new Api(); 47285c73a1SAndreas Gohr 48285c73a1SAndreas Gohr } 49285c73a1SAndreas Gohr 50285c73a1SAndreas Gohr public function tearDown() : void { 51285c73a1SAndreas Gohr global $USERINFO; 52285c73a1SAndreas Gohr global $AUTH_ACL; 53285c73a1SAndreas Gohr global $config_cascade; 54285c73a1SAndreas Gohr 55285c73a1SAndreas Gohr parent::tearDown(); 56285c73a1SAndreas Gohr 57285c73a1SAndreas Gohr $USERINFO = $this->userinfo; 58285c73a1SAndreas Gohr $AUTH_ACL = $this->oldAuthAcl; 59285c73a1SAndreas Gohr 60285c73a1SAndreas Gohr $name = $config_cascade['plainauth.users']['default']; 61285c73a1SAndreas Gohr copy($name . ".orig", $name); 62285c73a1SAndreas Gohr } 63285c73a1SAndreas Gohr 64884caed9SAndreas Gohr /** 65884caed9SAndreas Gohr * A regular (non-admin) user may check their own permissions. 66884caed9SAndreas Gohr */ 67884caed9SAndreas Gohr public function testCheckaclSelf() { 68285c73a1SAndreas Gohr global $conf; 69285c73a1SAndreas Gohr global $AUTH_ACL, $USERINFO; 70285c73a1SAndreas Gohr 71285c73a1SAndreas Gohr $conf['useacl'] = 1; 72285c73a1SAndreas Gohr $_SERVER['REMOTE_USER'] = 'john'; 73285c73a1SAndreas Gohr $USERINFO['grps'] = ['user']; 74285c73a1SAndreas Gohr $AUTH_ACL = [ 75285c73a1SAndreas Gohr '* @ALL 0', //none 76285c73a1SAndreas Gohr '* @user 2', //edit 77884caed9SAndreas Gohr ]; 78884caed9SAndreas Gohr 79884caed9SAndreas Gohr // no user given -> current user is used 80884caed9SAndreas Gohr $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', ['nice_page'])); 81884caed9SAndreas Gohr 82884caed9SAndreas Gohr // naming yourself explicitly is allowed too 83884caed9SAndreas Gohr $params = [ 84884caed9SAndreas Gohr 'nice_page', 85884caed9SAndreas Gohr 'john', 86884caed9SAndreas Gohr ['user'] 87884caed9SAndreas Gohr ]; 88884caed9SAndreas Gohr $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params)); 89884caed9SAndreas Gohr } 90884caed9SAndreas Gohr 91884caed9SAndreas Gohr /** 92*7ec464d9SAndreas Gohr * On a case-insensitive backend a user may check their own permissions even 93*7ec464d9SAndreas Gohr * when naming themselves in a different case than their logged-in name. 94*7ec464d9SAndreas Gohr */ 95*7ec464d9SAndreas Gohr public function testCheckaclSelfCaseInsensitiveBackend() { 96*7ec464d9SAndreas Gohr global $conf; 97*7ec464d9SAndreas Gohr global $AUTH_ACL, $USERINFO; 98*7ec464d9SAndreas Gohr global $auth; 99*7ec464d9SAndreas Gohr 100*7ec464d9SAndreas Gohr // logging in as "john" and naming "John" refer to the same user here 101*7ec464d9SAndreas Gohr $auth = new class extends \auth_plugin_authplain { 102*7ec464d9SAndreas Gohr public function isCaseSensitive() { 103*7ec464d9SAndreas Gohr return false; 104*7ec464d9SAndreas Gohr } 105*7ec464d9SAndreas Gohr }; 106*7ec464d9SAndreas Gohr 107*7ec464d9SAndreas Gohr $conf['useacl'] = 1; 108*7ec464d9SAndreas Gohr $_SERVER['REMOTE_USER'] = 'john'; 109*7ec464d9SAndreas Gohr $USERINFO['grps'] = ['user']; 110*7ec464d9SAndreas Gohr $AUTH_ACL = [ 111*7ec464d9SAndreas Gohr '* @ALL 0', //none 112*7ec464d9SAndreas Gohr '* @user 2', //edit 113*7ec464d9SAndreas Gohr ]; 114*7ec464d9SAndreas Gohr 115*7ec464d9SAndreas Gohr // naming yourself in a different case must not be treated as another user 116*7ec464d9SAndreas Gohr $params = [ 117*7ec464d9SAndreas Gohr 'nice_page', 118*7ec464d9SAndreas Gohr 'John', 119*7ec464d9SAndreas Gohr ['user'] 120*7ec464d9SAndreas Gohr ]; 121*7ec464d9SAndreas Gohr $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params)); 122*7ec464d9SAndreas Gohr } 123*7ec464d9SAndreas Gohr 124*7ec464d9SAndreas Gohr /** 125884caed9SAndreas Gohr * Checking another user's permissions is restricted to superusers and must 126884caed9SAndreas Gohr * be denied for a regular user. 127884caed9SAndreas Gohr */ 128884caed9SAndreas Gohr public function testCheckaclOtherUserDeniedForNonAdmin() { 129884caed9SAndreas Gohr global $conf; 130884caed9SAndreas Gohr global $AUTH_ACL, $USERINFO; 131884caed9SAndreas Gohr 132884caed9SAndreas Gohr $conf['useacl'] = 1; 133884caed9SAndreas Gohr $_SERVER['REMOTE_USER'] = 'john'; 134884caed9SAndreas Gohr $USERINFO['grps'] = ['user']; 135884caed9SAndreas Gohr $AUTH_ACL = [ 136884caed9SAndreas Gohr '* @ALL 0', //none 137884caed9SAndreas Gohr '* @user 2', //edit 138884caed9SAndreas Gohr ]; 139884caed9SAndreas Gohr 140884caed9SAndreas Gohr $this->expectException(AccessDeniedException::class); 141884caed9SAndreas Gohr $this->remote->call('core.aclCheck', ['nice_page', 'someoneelse', ['user']]); 142884caed9SAndreas Gohr } 143884caed9SAndreas Gohr 144884caed9SAndreas Gohr /** 145884caed9SAndreas Gohr * A superuser may check the permissions of arbitrary users and groups. 146884caed9SAndreas Gohr */ 147884caed9SAndreas Gohr public function testCheckaclOtherUsersAsAdmin() { 148884caed9SAndreas Gohr global $conf; 149884caed9SAndreas Gohr global $AUTH_ACL, $USERINFO; 150884caed9SAndreas Gohr /** @var auth_plugin_authplain $auth */ 151884caed9SAndreas Gohr global $auth; 152884caed9SAndreas Gohr 153884caed9SAndreas Gohr $conf['useacl'] = 1; 154884caed9SAndreas Gohr $_SERVER['REMOTE_USER'] = 'testuser'; // configured superuser, see _test/conf/local.php 155884caed9SAndreas Gohr $USERINFO['grps'] = ['user']; 156884caed9SAndreas Gohr $AUTH_ACL = [ 157884caed9SAndreas Gohr '* @ALL 0', //none 158884caed9SAndreas Gohr '* @user 2', //edit 159285c73a1SAndreas Gohr '* @more 4', //create 160285c73a1SAndreas Gohr 'nice_page user2 8' //upload 161285c73a1SAndreas Gohr ]; 162285c73a1SAndreas Gohr 163285c73a1SAndreas Gohr $auth->createUser("user1", "54321", "a User", "you@example.com"); 164285c73a1SAndreas Gohr $auth->createUser("user2", "543210", "You", "he@example.com"); 165285c73a1SAndreas Gohr $auth->createUser("mwuser", "12345", "Wiki User", "me@example.com", ['more']); //not in default group 166285c73a1SAndreas Gohr 167285c73a1SAndreas Gohr $params = [ 168285c73a1SAndreas Gohr 'nice_page', 169285c73a1SAndreas Gohr 'user1' 170285c73a1SAndreas Gohr ]; 1716e1ddc64SAndreas Gohr $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params)); 172285c73a1SAndreas Gohr 173285c73a1SAndreas Gohr $params = [ 174285c73a1SAndreas Gohr 'nice_page', 175285c73a1SAndreas Gohr 'mwuser', 1766e1ddc64SAndreas Gohr // member of group 'more' (automatically retrieved) 177285c73a1SAndreas Gohr ]; 1786e1ddc64SAndreas Gohr $this->assertEquals(AUTH_CREATE, $this->remote->call('core.aclCheck', $params)); 1796e1ddc64SAndreas Gohr 1806e1ddc64SAndreas Gohr $params = [ 1816e1ddc64SAndreas Gohr 'nice_page', 1826e1ddc64SAndreas Gohr 'mwuser', 1836e1ddc64SAndreas Gohr [] // member of group 'more' (automatically retrieved) 1846e1ddc64SAndreas Gohr ]; 1856e1ddc64SAndreas Gohr $this->assertEquals(AUTH_CREATE, $this->remote->call('core.aclCheck', $params)); 186285c73a1SAndreas Gohr 187285c73a1SAndreas Gohr $params = [ 188285c73a1SAndreas Gohr 'nice_page', 189285c73a1SAndreas Gohr 'notexistinguser', 190285c73a1SAndreas Gohr ['more'] 191285c73a1SAndreas Gohr ]; 1926e1ddc64SAndreas Gohr $this->assertEquals(AUTH_CREATE, $this->remote->call('core.aclCheck', $params)); 193285c73a1SAndreas Gohr 194285c73a1SAndreas Gohr $params = [ 195285c73a1SAndreas Gohr 'nice_page', 196285c73a1SAndreas Gohr 'user2', 1976e1ddc64SAndreas Gohr // (automatically retrieved) 198285c73a1SAndreas Gohr ]; 1996e1ddc64SAndreas Gohr $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', $params)); 200285c73a1SAndreas Gohr 201285c73a1SAndreas Gohr $params = [ 2026e1ddc64SAndreas Gohr 'nice_page', 2036e1ddc64SAndreas Gohr 'user2', 2046e1ddc64SAndreas Gohr [] // (automatically retrieved) 205285c73a1SAndreas Gohr ]; 2066e1ddc64SAndreas Gohr $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', $params)); 207285c73a1SAndreas Gohr 208285c73a1SAndreas Gohr $params = [ 209285c73a1SAndreas Gohr 'unknown_page', 210285c73a1SAndreas Gohr 'user2', 2116e1ddc64SAndreas Gohr // (automatically retrieved) 212285c73a1SAndreas Gohr ]; 2136e1ddc64SAndreas Gohr $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params)); 2146e1ddc64SAndreas Gohr 2156e1ddc64SAndreas Gohr $params = [ 2166e1ddc64SAndreas Gohr 'unknown_page', 2176e1ddc64SAndreas Gohr 'user2', 2186e1ddc64SAndreas Gohr [] // (automatically retrieved) 2196e1ddc64SAndreas Gohr ]; 2206e1ddc64SAndreas Gohr $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', $params)); 221285c73a1SAndreas Gohr 222285c73a1SAndreas Gohr $params = array( 223285c73a1SAndreas Gohr 'nice_page', 2246e1ddc64SAndreas Gohr 'testuser', // superuser set via conf 2256e1ddc64SAndreas Gohr // (automatically retrieved) 226285c73a1SAndreas Gohr ); 2276e1ddc64SAndreas Gohr $this->assertEquals(AUTH_ADMIN, $this->remote->call('core.aclCheck', $params)); 228285c73a1SAndreas Gohr } 229285c73a1SAndreas Gohr 230285c73a1SAndreas Gohr} 231