11468a128SAndreas Gohr<?php 21468a128SAndreas Gohr 31468a128SAndreas Gohrnamespace dokuwiki\test\Remote; 41468a128SAndreas Gohr 51468a128SAndreas Gohruse dokuwiki\Remote\AccessDeniedException; 61468a128SAndreas Gohruse dokuwiki\Remote\Api; 7*801ecc14SAndreas Gohruse dokuwiki\Remote\ApiCall; 81468a128SAndreas Gohruse dokuwiki\Remote\RemoteException; 9*801ecc14SAndreas Gohruse dokuwiki\test\mock\AuthPlugin; 10*801ecc14SAndreas Gohruse dokuwiki\test\Remote\Mock\ApiCore; 11*801ecc14SAndreas Gohruse dokuwiki\test\Remote\Mock\TestPlugin1; 12*801ecc14SAndreas Gohruse dokuwiki\test\Remote\Mock\TestPlugin2; 131468a128SAndreas Gohr 14*801ecc14SAndreas Gohrclass ApiTest extends \DokuWikiTest 15*801ecc14SAndreas Gohr{ 161468a128SAndreas Gohr 171468a128SAndreas Gohr protected $userinfo; 181468a128SAndreas Gohr 191468a128SAndreas Gohr /** @var Api */ 201468a128SAndreas Gohr protected $remote; 211468a128SAndreas Gohr 22*801ecc14SAndreas Gohr public function setUp(): void 23*801ecc14SAndreas Gohr { 241468a128SAndreas Gohr parent::setUp(); 251468a128SAndreas Gohr global $plugin_controller; 261468a128SAndreas Gohr global $conf; 271468a128SAndreas Gohr global $USERINFO; 281468a128SAndreas Gohr global $auth; 291468a128SAndreas Gohr 301468a128SAndreas Gohr parent::setUp(); 311468a128SAndreas Gohr 321468a128SAndreas Gohr // mock plugin controller to return our test plugins 331468a128SAndreas Gohr $pluginManager = $this->createMock('dokuwiki\Extension\PluginController'); 341468a128SAndreas Gohr $pluginManager->method('getList')->willReturn(array('testplugin', 'testplugin2')); 351468a128SAndreas Gohr $pluginManager->method('load')->willReturnCallback( 361468a128SAndreas Gohr function ($type, $plugin) { 371468a128SAndreas Gohr if ($plugin == 'testplugin2') { 38*801ecc14SAndreas Gohr return new TestPlugin2(); 391468a128SAndreas Gohr } else { 40*801ecc14SAndreas Gohr return new TestPlugin1(); 411468a128SAndreas Gohr } 421468a128SAndreas Gohr } 431468a128SAndreas Gohr ); 441468a128SAndreas Gohr $plugin_controller = $pluginManager; 451468a128SAndreas Gohr 461468a128SAndreas Gohr $conf['remote'] = 1; 471468a128SAndreas Gohr $conf['remoteuser'] = '!!not set!!'; 481468a128SAndreas Gohr $conf['useacl'] = 0; 491468a128SAndreas Gohr 501468a128SAndreas Gohr $this->userinfo = $USERINFO; 511468a128SAndreas Gohr $this->remote = new Api(); 521468a128SAndreas Gohr 531468a128SAndreas Gohr $auth = new AuthPlugin(); 541468a128SAndreas Gohr } 551468a128SAndreas Gohr 56*801ecc14SAndreas Gohr public function tearDown(): void 57*801ecc14SAndreas Gohr { 581468a128SAndreas Gohr global $USERINFO; 591468a128SAndreas Gohr $USERINFO = $this->userinfo; 601468a128SAndreas Gohr 611468a128SAndreas Gohr } 621468a128SAndreas Gohr 63*801ecc14SAndreas Gohr public function testPluginMethods() 64*801ecc14SAndreas Gohr { 651468a128SAndreas Gohr $methods = $this->remote->getPluginMethods(); 661468a128SAndreas Gohr $actual = array_keys($methods); 671468a128SAndreas Gohr sort($actual); 681468a128SAndreas Gohr $expect = array( 691468a128SAndreas Gohr 'plugin.testplugin.method1', 701468a128SAndreas Gohr 'plugin.testplugin.method2', 711468a128SAndreas Gohr 'plugin.testplugin.methodString', 721468a128SAndreas Gohr 'plugin.testplugin.method2ext', 731468a128SAndreas Gohr 'plugin.testplugin.publicCall', 741468a128SAndreas Gohr 751468a128SAndreas Gohr 'plugin.testplugin2.commented' 761468a128SAndreas Gohr ); 771468a128SAndreas Gohr sort($expect); 781468a128SAndreas Gohr $this->assertEquals($expect, $actual); 791468a128SAndreas Gohr } 801468a128SAndreas Gohr 81*801ecc14SAndreas Gohr public function testPluginDescriptors() 82*801ecc14SAndreas Gohr { 831468a128SAndreas Gohr $methods = $this->remote->getPluginMethods(); 841468a128SAndreas Gohr $this->assertEquals( 851468a128SAndreas Gohr [ 861468a128SAndreas Gohr 'str' => [ 871468a128SAndreas Gohr 'type' => 'string', 881468a128SAndreas Gohr 'description' => 'some more parameter description', 89*801ecc14SAndreas Gohr 'optional' => false, 901468a128SAndreas Gohr ], 911468a128SAndreas Gohr 'int' => [ 921468a128SAndreas Gohr 'type' => 'int', 931468a128SAndreas Gohr 'description' => '', 94*801ecc14SAndreas Gohr 'optional' => false, 951468a128SAndreas Gohr ], 961468a128SAndreas Gohr 'bool' => [ 971468a128SAndreas Gohr 'type' => 'bool', 981468a128SAndreas Gohr 'description' => '', 99*801ecc14SAndreas Gohr 'optional' => false, 1001468a128SAndreas Gohr ], 101*801ecc14SAndreas Gohr 'array' => [ 102*801ecc14SAndreas Gohr 'type' => 'array', 1031468a128SAndreas Gohr 'description' => '', 104*801ecc14SAndreas Gohr 'optional' => true, 105*801ecc14SAndreas Gohr 'default' => [], 1061468a128SAndreas Gohr ], 1071468a128SAndreas Gohr ], 1081468a128SAndreas Gohr $methods['plugin.testplugin2.commented']->getArgs() 1091468a128SAndreas Gohr ); 1101468a128SAndreas Gohr 1111468a128SAndreas Gohr $this->assertEquals( 1121468a128SAndreas Gohr [ 1131468a128SAndreas Gohr 'type' => 'array', 1141468a128SAndreas Gohr 'description' => '', 1151468a128SAndreas Gohr ], 1161468a128SAndreas Gohr $methods['plugin.testplugin2.commented']->getReturn() 1171468a128SAndreas Gohr ); 1181468a128SAndreas Gohr 1191468a128SAndreas Gohr $this->assertEquals(0, $methods['plugin.testplugin2.commented']->isPublic()); 1201468a128SAndreas Gohr $this->assertStringContainsString( 1211468a128SAndreas Gohr 'This is a dummy method', 1221468a128SAndreas Gohr $methods['plugin.testplugin2.commented']->getSummary() 1231468a128SAndreas Gohr ); 1241468a128SAndreas Gohr } 1251468a128SAndreas Gohr 1261468a128SAndreas Gohr public function testHasAccessSuccess() 1271468a128SAndreas Gohr { 1281468a128SAndreas Gohr global $conf; 1291468a128SAndreas Gohr $conf['remoteuser'] = ''; 1301468a128SAndreas Gohr 1311468a128SAndreas Gohr $this->remote->ensureAccessIsAllowed(new ApiCall('time')); 1321468a128SAndreas Gohr $this->assertTrue(true); 1331468a128SAndreas Gohr } 1341468a128SAndreas Gohr 135*801ecc14SAndreas Gohr public function testHasAccessFailAcl() 136*801ecc14SAndreas Gohr { 1371468a128SAndreas Gohr global $conf; 1381468a128SAndreas Gohr $conf['useacl'] = 1; 1391468a128SAndreas Gohr 1401468a128SAndreas Gohr $this->expectException(AccessDeniedException::class); 1411468a128SAndreas Gohr $this->remote->ensureAccessIsAllowed(new ApiCall('time')); 1421468a128SAndreas Gohr } 1431468a128SAndreas Gohr 144*801ecc14SAndreas Gohr public function testHasAccessSuccessAclEmptyRemoteUser() 145*801ecc14SAndreas Gohr { 1461468a128SAndreas Gohr global $conf; 1471468a128SAndreas Gohr $conf['useacl'] = 1; 1481468a128SAndreas Gohr $conf['remoteuser'] = ''; 1491468a128SAndreas Gohr 1501468a128SAndreas Gohr $this->remote->ensureAccessIsAllowed(new ApiCall('time')); 1511468a128SAndreas Gohr $this->assertTrue(true); 1521468a128SAndreas Gohr } 1531468a128SAndreas Gohr 154*801ecc14SAndreas Gohr public function testHasAccessSuccessAcl() 155*801ecc14SAndreas Gohr { 1561468a128SAndreas Gohr global $conf; 1571468a128SAndreas Gohr global $USERINFO; 1581468a128SAndreas Gohr $conf['useacl'] = 1; 1591468a128SAndreas Gohr $conf['remoteuser'] = '@grp,@grp2'; 1601468a128SAndreas Gohr $USERINFO['grps'] = array('grp'); 1611468a128SAndreas Gohr 1621468a128SAndreas Gohr $this->remote->ensureAccessIsAllowed(new ApiCall('time')); 1631468a128SAndreas Gohr $this->assertTrue(true); 1641468a128SAndreas Gohr } 1651468a128SAndreas Gohr 166*801ecc14SAndreas Gohr public function testHasAccessFailAcl2() 167*801ecc14SAndreas Gohr { 1681468a128SAndreas Gohr global $conf; 1691468a128SAndreas Gohr global $USERINFO; 1701468a128SAndreas Gohr $conf['useacl'] = 1; 1711468a128SAndreas Gohr $conf['remoteuser'] = '@grp'; 1721468a128SAndreas Gohr $USERINFO['grps'] = array('grp1'); 1731468a128SAndreas Gohr 1741468a128SAndreas Gohr $this->expectException(AccessDeniedException::class); 1751468a128SAndreas Gohr $this->remote->ensureAccessIsAllowed(new ApiCall('time')); 1761468a128SAndreas Gohr } 1771468a128SAndreas Gohr 178*801ecc14SAndreas Gohr public function testIsEnabledFail1() 179*801ecc14SAndreas Gohr { 1801468a128SAndreas Gohr global $conf; 1811468a128SAndreas Gohr $conf['remote'] = 0; 1821468a128SAndreas Gohr $this->expectException(AccessDeniedException::class); 1831468a128SAndreas Gohr $this->remote->ensureApiIsEnabled(); 1841468a128SAndreas Gohr } 1851468a128SAndreas Gohr 186*801ecc14SAndreas Gohr public function testIsEnabledFail2() 187*801ecc14SAndreas Gohr { 1881468a128SAndreas Gohr global $conf; 1891468a128SAndreas Gohr $conf['remoteuser'] = '!!not set!!'; 1901468a128SAndreas Gohr $this->expectException(AccessDeniedException::class); 1911468a128SAndreas Gohr $this->remote->ensureApiIsEnabled(); 1921468a128SAndreas Gohr } 1931468a128SAndreas Gohr 194*801ecc14SAndreas Gohr public function testIsEnabledSuccess() 195*801ecc14SAndreas Gohr { 1961468a128SAndreas Gohr global $conf; 1971468a128SAndreas Gohr $conf['remote'] = 1; 1981468a128SAndreas Gohr $conf['remoteuser'] = ''; 1991468a128SAndreas Gohr $this->remote->ensureApiIsEnabled(); 2001468a128SAndreas Gohr $this->assertTrue(true); 2011468a128SAndreas Gohr } 2021468a128SAndreas Gohr 2031468a128SAndreas Gohr 204*801ecc14SAndreas Gohr public function testGeneralCoreFunctionWithoutArguments() 205*801ecc14SAndreas Gohr { 2061468a128SAndreas Gohr global $conf; 2071468a128SAndreas Gohr global $USERINFO; 2081468a128SAndreas Gohr $conf['remote'] = 1; 2091468a128SAndreas Gohr $conf['remoteuser'] = ''; 2101468a128SAndreas Gohr $conf['useacl'] = 1; 2111468a128SAndreas Gohr $USERINFO['grps'] = array('grp'); 2121468a128SAndreas Gohr $remoteApi = new Api(); 213*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 2141468a128SAndreas Gohr 2151468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.stringTestMethod'), 'success'); 2161468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.intTestMethod'), 42); 2171468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.floatTestMethod'), 3.14159265); 2181468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.dateTestMethod'), 2623452346); 2191468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.fileTestMethod'), 'file content'); 2201468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.voidTestMethod'), null); 2211468a128SAndreas Gohr } 2221468a128SAndreas Gohr 223*801ecc14SAndreas Gohr public function testGeneralCoreFunctionOnArgumentMismatch() 224*801ecc14SAndreas Gohr { 2251468a128SAndreas Gohr global $conf; 2261468a128SAndreas Gohr $conf['remote'] = 1; 2271468a128SAndreas Gohr $remoteApi = new Api(); 228*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 2291468a128SAndreas Gohr 2301468a128SAndreas Gohr try { 2311468a128SAndreas Gohr $remoteApi->call('wiki.voidTestMethod', array('something')); 2321468a128SAndreas Gohr $this->fail('Expects RemoteException to be raised'); 2331468a128SAndreas Gohr } catch (RemoteException $th) { 2341468a128SAndreas Gohr $this->assertEquals(-32604, $th->getCode()); 2351468a128SAndreas Gohr } 2361468a128SAndreas Gohr } 2371468a128SAndreas Gohr 238*801ecc14SAndreas Gohr public function testGeneralCoreFunctionWithArguments() 239*801ecc14SAndreas Gohr { 2401468a128SAndreas Gohr global $conf; 2411468a128SAndreas Gohr global $USERINFO; 2421468a128SAndreas Gohr $conf['remote'] = 1; 2431468a128SAndreas Gohr $conf['remoteuser'] = ''; 2441468a128SAndreas Gohr $conf['useacl'] = 1; 2451468a128SAndreas Gohr 2461468a128SAndreas Gohr $remoteApi = new Api(); 247*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 2481468a128SAndreas Gohr 2491468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.oneStringArgMethod', array('string')), 'string'); 2501468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.twoArgMethod', array('string', 1)), array('string', 1)); 2511468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.twoArgWithDefaultArg', array('string')), array('string', 'default')); 2521468a128SAndreas Gohr $this->assertEquals($remoteApi->call('wiki.twoArgWithDefaultArg', array('string', 'another')), array('string', 'another')); 2531468a128SAndreas Gohr } 2541468a128SAndreas Gohr 255*801ecc14SAndreas Gohr public function testGeneralCoreFunctionOnArgumentMissing() 256*801ecc14SAndreas Gohr { 2571468a128SAndreas Gohr global $conf; 2581468a128SAndreas Gohr $conf['remote'] = 1; 2591468a128SAndreas Gohr $conf['remoteuser'] = ''; 2601468a128SAndreas Gohr $remoteApi = new Api(); 261*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 2621468a128SAndreas Gohr 263*801ecc14SAndreas Gohr $this->expectException(RemoteException::class); 264*801ecc14SAndreas Gohr $this->expectExceptionCode(-32602); 265*801ecc14SAndreas Gohr 2661468a128SAndreas Gohr $remoteApi->call('wiki.twoArgWithDefaultArg', array()); 2671468a128SAndreas Gohr } 2681468a128SAndreas Gohr 269*801ecc14SAndreas Gohr public function testPluginCallMethods() 270*801ecc14SAndreas Gohr { 2711468a128SAndreas Gohr global $conf; 2721468a128SAndreas Gohr global $USERINFO; 2731468a128SAndreas Gohr $conf['remote'] = 1; 2741468a128SAndreas Gohr $conf['remoteuser'] = ''; 2751468a128SAndreas Gohr $conf['useacl'] = 1; 2761468a128SAndreas Gohr 2771468a128SAndreas Gohr $remoteApi = new Api(); 2781468a128SAndreas Gohr $this->assertEquals($remoteApi->call('plugin.testplugin.method1'), null); 2791468a128SAndreas Gohr $this->assertEquals($remoteApi->call('plugin.testplugin.method2', array('string', 7)), array('string', 7, false)); 2801468a128SAndreas Gohr $this->assertEquals($remoteApi->call('plugin.testplugin.method2ext', array('string', 7, true)), array('string', 7, true)); 2811468a128SAndreas Gohr $this->assertEquals($remoteApi->call('plugin.testplugin.methodString'), 'success'); 2821468a128SAndreas Gohr } 2831468a128SAndreas Gohr 284*801ecc14SAndreas Gohr public function testPluginCallMethodsOnArgumentMissing() 285*801ecc14SAndreas Gohr { 2861468a128SAndreas Gohr global $conf; 2871468a128SAndreas Gohr $conf['remote'] = 1; 2881468a128SAndreas Gohr $conf['remoteuser'] = ''; 2891468a128SAndreas Gohr $remoteApi = new Api(); 290*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 2911468a128SAndreas Gohr 292*801ecc14SAndreas Gohr $this->expectException(RemoteException::class); 293*801ecc14SAndreas Gohr $this->expectExceptionCode(-32602); 2941468a128SAndreas Gohr $remoteApi->call('plugin.testplugin.method2', array()); 2951468a128SAndreas Gohr } 2961468a128SAndreas Gohr 297*801ecc14SAndreas Gohr public function testNotExistingCall() 298*801ecc14SAndreas Gohr { 2991468a128SAndreas Gohr global $conf; 3001468a128SAndreas Gohr $conf['remote'] = 1; 3011468a128SAndreas Gohr $conf['remoteuser'] = ''; 3021468a128SAndreas Gohr 3031468a128SAndreas Gohr $this->expectException(RemoteException::class); 3041468a128SAndreas Gohr $this->expectExceptionCode(-32603); 3051468a128SAndreas Gohr 3061468a128SAndreas Gohr $remoteApi = new Api(); 3071468a128SAndreas Gohr $remoteApi->call('does.not exist'); // unknown method type 3081468a128SAndreas Gohr } 3091468a128SAndreas Gohr 310*801ecc14SAndreas Gohr public function testPublicCallCore() 311*801ecc14SAndreas Gohr { 3121468a128SAndreas Gohr global $conf; 3131468a128SAndreas Gohr $conf['useacl'] = 1; 3141468a128SAndreas Gohr $conf['remote'] = 1; 3151468a128SAndreas Gohr $conf['remoteuser'] = 'restricted'; 3161468a128SAndreas Gohr $remoteApi = new Api(); 317*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 3181468a128SAndreas Gohr $this->assertTrue($remoteApi->call('wiki.publicCall')); 3191468a128SAndreas Gohr } 3201468a128SAndreas Gohr 321*801ecc14SAndreas Gohr public function testPublicCallPlugin() 322*801ecc14SAndreas Gohr { 3231468a128SAndreas Gohr global $conf; 3241468a128SAndreas Gohr $conf['useacl'] = 1; 3251468a128SAndreas Gohr $conf['remote'] = 1; 3261468a128SAndreas Gohr $conf['remoteuser'] = 'restricted'; 3271468a128SAndreas Gohr $remoteApi = new Api(); 3281468a128SAndreas Gohr $this->assertTrue($remoteApi->call('plugin.testplugin.publicCall')); 3291468a128SAndreas Gohr } 3301468a128SAndreas Gohr 331*801ecc14SAndreas Gohr public function testPublicCallCoreDeny() 332*801ecc14SAndreas Gohr { 3331468a128SAndreas Gohr global $conf; 3341468a128SAndreas Gohr $conf['useacl'] = 1; 3351468a128SAndreas Gohr $this->expectException(AccessDeniedException::class); 3361468a128SAndreas Gohr $remoteApi = new Api(); 337*801ecc14SAndreas Gohr $remoteApi->getCoreMethods(new ApiCore()); 3381468a128SAndreas Gohr $remoteApi->call('wiki.stringTestMethod'); 3391468a128SAndreas Gohr } 3401468a128SAndreas Gohr 341*801ecc14SAndreas Gohr public function testPublicCallPluginDeny() 342*801ecc14SAndreas Gohr { 3431468a128SAndreas Gohr global $conf; 3441468a128SAndreas Gohr $conf['useacl'] = 1; 3451468a128SAndreas Gohr $this->expectException(AccessDeniedException::class); 3461468a128SAndreas Gohr $remoteApi = new Api(); 3471468a128SAndreas Gohr $remoteApi->call('plugin.testplugin.methodString'); 3481468a128SAndreas Gohr } 3491468a128SAndreas Gohr} 350