[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/_test/tests/inc/ -> remote.test.php (source)

   1  <?php
   2  
   3  use dokuwiki\test\mock\AuthPlugin;
   4  use dokuwiki\Extension\RemotePlugin;
   5  use dokuwiki\Remote\Api;
   6  use dokuwiki\Remote\RemoteException;
   7  
   8  class RemoteAPICoreTest {
   9  
  10      function getRemoteInfo() {
  11          return array(
  12              'wiki.stringTestMethod' => array(
  13                  'args' => array(),
  14                  'return' => 'string',
  15                  'doc' => 'Test method',
  16                  'name' => 'stringTestMethod',
  17              ), 'wiki.intTestMethod' => array(
  18                  'args' => array(),
  19                  'return' => 'int',
  20                  'doc' => 'Test method',
  21                  'name' => 'intTestMethod',
  22              ), 'wiki.floatTestMethod' => array(
  23                  'args' => array(),
  24                  'return' => 'float',
  25                  'doc' => 'Test method',
  26                  'name' => 'floatTestMethod',
  27              ), 'wiki.dateTestMethod' => array(
  28                  'args' => array(),
  29                  'return' => 'date',
  30                  'doc' => 'Test method',
  31                  'name' => 'dateTestMethod',
  32              ), 'wiki.fileTestMethod' => array(
  33                  'args' => array(),
  34                  'return' => 'file',
  35                  'doc' => 'Test method',
  36                  'name' => 'fileTestMethod',
  37              ), 'wiki.voidTestMethod' => array(
  38                  'args' => array(),
  39                  'return' => 'void',
  40                  'doc' => 'Test method',
  41                  'name' => 'voidTestMethod',
  42              ),  'wiki.oneStringArgMethod' => array(
  43                  'args' => array('string'),
  44                  'return' => 'string',
  45                  'doc' => 'Test method',
  46                  'name' => 'oneStringArgMethod',
  47              ), 'wiki.twoArgMethod' => array(
  48                  'args' => array('string', 'int'),
  49                  'return' => 'array',
  50                  'doc' => 'Test method',
  51                  'name' => 'twoArgMethod',
  52              ), 'wiki.twoArgWithDefaultArg' => array(
  53                  'args' => array('string', 'string'),
  54                  'return' => 'string',
  55                  'doc' => 'Test method',
  56                  'name' => 'twoArgWithDefaultArg',
  57              ), 'wiki.publicCall' => array(
  58                  'args' => array(),
  59                  'return' => 'boolean',
  60                  'doc' => 'testing for public access',
  61                  'name' => 'publicCall',
  62                  'public' => 1
  63              )
  64          );
  65      }
  66      function stringTestMethod() { return 'success'; }
  67      function intTestMethod() { return 42; }
  68      function floatTestMethod() { return 3.14159265; }
  69      function dateTestMethod() { return 2623452346; }
  70      function fileTestMethod() { return 'file content'; }
  71      function voidTestMethod() { return null; }
  72      function oneStringArgMethod($arg) {return $arg; }
  73      function twoArgMethod($string, $int) { return array($string, $int); }
  74      function twoArgWithDefaultArg($string1, $string2 = 'default') { return array($string1, $string2); }
  75      function publicCall() {return true;}
  76  
  77  }
  78  
  79  class remote_plugin_testplugin extends RemotePlugin {
  80      function _getMethods() {
  81          return array(
  82              'method1' => array(
  83                  'args' => array(),
  84                  'return' => 'void'
  85              ), 'methodString' => array(
  86                  'args' => array(),
  87                  'return' => 'string'
  88              ), 'method2' => array(
  89                  'args' => array('string', 'int'),
  90                  'return' => 'array',
  91                  'name' => 'method2',
  92              ), 'method2ext' => array(
  93                  'args' => array('string', 'int', 'bool'),
  94                  'return' => 'array',
  95                  'name' => 'method2',
  96              ), 'publicCall' => array(
  97                  'args' => array(),
  98                  'return' => 'boolean',
  99                  'doc' => 'testing for public access',
 100                  'name' => 'publicCall',
 101                  'public' => 1
 102              )
 103          );
 104      }
 105  
 106      function method1() { return null; }
 107      function methodString() { return 'success'; }
 108      function method2($str, $int, $bool = false) { return array($str, $int, $bool); }
 109      function publicCall() {return true;}
 110  }
 111  
 112  class remote_plugin_testplugin2 extends RemotePlugin {
 113      /**
 114       * This is a dummy method
 115       *
 116       * @param string $str some more parameter description
 117       * @param int $int
 118       * @param bool $bool
 119       * @param Object $unknown
 120       * @return array
 121       */
 122      public function commented($str, $int, $bool, $unknown) { return array($str, $int, $bool); }
 123  
 124      private function privateMethod() {return true;}
 125      protected function protectedMethod() {return true;}
 126      public function _underscore() {return true;}
 127  }
 128  
 129  
 130  
 131  class remote_test extends DokuWikiTest {
 132  
 133      protected $userinfo;
 134  
 135      /** @var  Api */
 136      protected $remote;
 137  
 138      function setUp() : void {
 139          parent::setUp();
 140          global $plugin_controller;
 141          global $conf;
 142          global $USERINFO;
 143          global $auth;
 144  
 145          parent::setUp();
 146  
 147          // mock plugin controller to return our test plugins
 148          $pluginManager = $this->createMock('dokuwiki\Extension\PluginController');
 149          $pluginManager->method('getList')->willReturn(array('testplugin', 'testplugin2'));
 150          $pluginManager->method('load')->willReturnCallback(
 151              function($type, $plugin) {
 152                  if($plugin == 'testplugin2') {
 153                      return new remote_plugin_testplugin2();
 154                  } else {
 155                      return new remote_plugin_testplugin();
 156                  }
 157              }
 158          );
 159          $plugin_controller = $pluginManager;
 160  
 161          $conf['remote'] = 1;
 162          $conf['remoteuser'] = '!!not set!!';
 163          $conf['useacl'] = 0;
 164  
 165          $this->userinfo = $USERINFO;
 166          $this->remote = new Api();
 167  
 168          $auth = new AuthPlugin();
 169      }
 170  
 171      function tearDown() : void {
 172          global $USERINFO;
 173          $USERINFO = $this->userinfo;
 174  
 175      }
 176  
 177      function test_pluginMethods() {
 178          $methods = $this->remote->getPluginMethods();
 179          $actual = array_keys($methods);
 180          sort($actual);
 181          $expect = array(
 182              'plugin.testplugin.method1',
 183              'plugin.testplugin.method2',
 184              'plugin.testplugin.methodString',
 185              'plugin.testplugin.method2ext',
 186              'plugin.testplugin.publicCall',
 187  
 188              'plugin.testplugin2.commented'
 189          );
 190          sort($expect);
 191          $this->assertEquals($expect,$actual);
 192      }
 193  
 194      function test_pluginDescriptors() {
 195          $methods = $this->remote->getPluginMethods();
 196          $this->assertEquals(array('string','int','bool','string'), $methods['plugin.testplugin2.commented']['args']);
 197          $this->assertEquals('array', $methods['plugin.testplugin2.commented']['return']);
 198          $this->assertEquals(0, $methods['plugin.testplugin2.commented']['public']);
 199          $this->assertStringContainsString('This is a dummy method', $methods['plugin.testplugin2.commented']['doc']);
 200          $this->assertStringContainsString('string $str some more parameter description', $methods['plugin.testplugin2.commented']['doc']);
 201      }
 202  
 203      function test_hasAccessSuccess() {
 204          global $conf;
 205          $conf['remoteuser'] = '';
 206          $this->assertTrue($this->remote->hasAccess());
 207      }
 208  
 209      function test_hasAccessFail() {
 210          global $conf;
 211          $conf['remote'] = 0;
 212          // the hasAccess() should throw a Exception to keep the same semantics with xmlrpc.php.
 213          // because the user(xmlrpc) check remote before .--> (!$conf['remote']) die('XML-RPC server not enabled.');
 214          // so it must be a Exception when get here.
 215          $this->expectException(\dokuwiki\Remote\AccessDeniedException::class);
 216          $this->remote->hasAccess();
 217      }
 218  
 219      function test_hasAccessFailAcl() {
 220          global $conf;
 221          $conf['useacl'] = 1;
 222          $this->assertFalse($this->remote->hasAccess());
 223      }
 224  
 225      function test_hasAccessSuccessAclEmptyRemoteUser() {
 226          global $conf;
 227          $conf['useacl'] = 1;
 228          $conf['remoteuser'] = '';
 229  
 230          $this->assertTrue($this->remote->hasAccess());
 231      }
 232  
 233      function test_hasAccessSuccessAcl() {
 234          global $conf;
 235          global $USERINFO;
 236          $conf['useacl'] = 1;
 237          $conf['remoteuser'] = '@grp,@grp2';
 238          $USERINFO['grps'] = array('grp');
 239          $this->assertTrue($this->remote->hasAccess());
 240      }
 241  
 242      function test_hasAccessFailAcl2() {
 243          global $conf;
 244          global $USERINFO;
 245          $conf['useacl'] = 1;
 246          $conf['remoteuser'] = '@grp';
 247          $USERINFO['grps'] = array('grp1');
 248  
 249          $this->assertFalse($this->remote->hasAccess());
 250      }
 251  
 252  
 253      function test_forceAccessSuccess() {
 254          global $conf;
 255          $conf['remote'] = 1;
 256          $conf['remoteuser'] = '';
 257          $this->remote->forceAccess(); // no exception should occur
 258          $this->assertTrue(true); // avoid being marked as risky for having no assertion
 259      }
 260  
 261      function test_forceAccessFail() {
 262          global $conf;
 263          $conf['remote'] = 0;
 264  
 265          try {
 266              $this->remote->forceAccess();
 267              $this->fail('Expects RemoteException to be raised');
 268          } catch (RemoteException $th) {
 269              $this->assertEquals(-32604, $th->getCode());
 270          }
 271      }
 272  
 273      function test_generalCoreFunctionWithoutArguments() {
 274          global $conf;
 275          global $USERINFO;
 276          $conf['remote'] = 1;
 277          $conf['remoteuser'] = '';
 278          $conf['useacl'] = 1;
 279          $USERINFO['grps'] = array('grp');
 280          $remoteApi = new Api();
 281          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 282  
 283          $this->assertEquals($remoteApi->call('wiki.stringTestMethod'), 'success');
 284          $this->assertEquals($remoteApi->call('wiki.intTestMethod'), 42);
 285          $this->assertEquals($remoteApi->call('wiki.floatTestMethod'), 3.14159265);
 286          $this->assertEquals($remoteApi->call('wiki.dateTestMethod'), 2623452346);
 287          $this->assertEquals($remoteApi->call('wiki.fileTestMethod'), 'file content');
 288          $this->assertEquals($remoteApi->call('wiki.voidTestMethod'), null);
 289      }
 290  
 291      function test_generalCoreFunctionOnArgumentMismatch() {
 292          global $conf;
 293          $conf['remote'] = 1;
 294          $remoteApi = new Api();
 295          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 296  
 297          try {
 298              $remoteApi->call('wiki.voidTestMethod', array('something'));
 299              $this->fail('Expects RemoteException to be raised');
 300          } catch (RemoteException $th) {
 301              $this->assertEquals(-32604, $th->getCode());
 302          }
 303      }
 304  
 305      function test_generalCoreFunctionWithArguments() {
 306          global $conf;
 307          global $USERINFO;
 308          $conf['remote'] = 1;
 309          $conf['remoteuser'] = '';
 310          $conf['useacl'] = 1;
 311  
 312          $remoteApi = new Api();
 313          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 314  
 315          $this->assertEquals($remoteApi->call('wiki.oneStringArgMethod', array('string')), 'string');
 316          $this->assertEquals($remoteApi->call('wiki.twoArgMethod', array('string', 1)), array('string' , 1));
 317          $this->assertEquals($remoteApi->call('wiki.twoArgWithDefaultArg', array('string')), array('string', 'default'));
 318          $this->assertEquals($remoteApi->call('wiki.twoArgWithDefaultArg', array('string', 'another')), array('string', 'another'));
 319      }
 320  
 321      function test_generalCoreFunctionOnArgumentMissing() {
 322          global $conf;
 323          $conf['remote'] = 1;
 324          $conf['remoteuser'] = '';
 325          $remoteApi = new Api();
 326          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 327  
 328          try {
 329              $remoteApi->call('wiki.twoArgWithDefaultArg', array());
 330              $this->fail('Expects RemoteException to be raised');
 331          } catch (RemoteException $th) {
 332              $this->assertEquals(-32603, $th->getCode());
 333          }
 334      }
 335  
 336      function test_pluginCallMethods() {
 337          global $conf;
 338          global $USERINFO;
 339          $conf['remote'] = 1;
 340          $conf['remoteuser'] = '';
 341          $conf['useacl'] = 1;
 342  
 343          $remoteApi = new Api();
 344          $this->assertEquals($remoteApi->call('plugin.testplugin.method1'), null);
 345          $this->assertEquals($remoteApi->call('plugin.testplugin.method2', array('string', 7)), array('string', 7, false));
 346          $this->assertEquals($remoteApi->call('plugin.testplugin.method2ext', array('string', 7, true)), array('string', 7, true));
 347          $this->assertEquals($remoteApi->call('plugin.testplugin.methodString'), 'success');
 348      }
 349  
 350      function test_pluginCallMethodsOnArgumentMissing() {
 351          global $conf;
 352          $conf['remote'] = 1;
 353          $conf['remoteuser'] = '';
 354          $remoteApi = new Api();
 355          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 356  
 357          try {
 358              $remoteApi->call('plugin.testplugin.method2', array());
 359              $this->fail('Expects RemoteException to be raised');
 360          } catch (RemoteException $th) {
 361              $this->assertEquals(-32603, $th->getCode());
 362          }
 363      }
 364  
 365      function test_notExistingCall() {
 366          global $conf;
 367          $conf['remote'] = 1;
 368  
 369          $this->expectException(RemoteException::class);
 370          $this->expectExceptionCode(-32603);
 371  
 372          $remoteApi = new Api();
 373          $remoteApi->call('invalid method'); // no '.'
 374          $remoteApi->call('does.not exist'); // unknown method type
 375      }
 376  
 377      function test_publicCallCore() {
 378          global $conf;
 379          $conf['useacl'] = 1;
 380          $remoteApi = new Api();
 381          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 382          $this->assertTrue($remoteApi->call('wiki.publicCall'));
 383      }
 384  
 385      function test_publicCallPlugin() {
 386          global $conf;
 387          $conf['useacl'] = 1;
 388          $remoteApi = new Api();
 389          $this->assertTrue($remoteApi->call('plugin.testplugin.publicCall'));
 390      }
 391  
 392      function test_publicCallCoreDeny() {
 393          global $conf;
 394          $conf['useacl'] = 1;
 395          $this->expectException(\dokuwiki\Remote\AccessDeniedException::class);
 396          $remoteApi = new Api();
 397          $remoteApi->getCoreMethods(new RemoteAPICoreTest());
 398          $remoteApi->call('wiki.stringTestMethod');
 399      }
 400  
 401      function test_publicCallPluginDeny() {
 402          global $conf;
 403          $conf['useacl'] = 1;
 404          $this->expectException(\dokuwiki\Remote\AccessDeniedException::class);
 405          $remoteApi = new Api();
 406          $remoteApi->call('plugin.testplugin.methodString');
 407      }
 408  
 409      function test_pluginCallCustomPath() {
 410          global $conf;
 411          global $USERINFO;
 412          $conf['remote'] = 1;
 413          $conf['remoteuser'] = '';
 414          $conf['useacl'] = 1;
 415          global $EVENT_HANDLER;
 416          $EVENT_HANDLER->register_hook('RPC_CALL_ADD', 'BEFORE', $this, 'pluginCallCustomPathRegister');
 417  
 418          $remoteApi = new Api();
 419          $result = $remoteApi->call('custom.path');
 420          $this->assertEquals($result, 'success');
 421      }
 422  
 423      function pluginCallCustomPathRegister(&$event, $param) {
 424          $event->data['custom.path'] = array('testplugin', 'methodString');
 425      }
 426  }