diff options
-rw-r--r-- | inc/Remote/Api.php | 2 | ||||
-rw-r--r-- | inc/Remote/JsonRpcServer.php | 85 | ||||
-rw-r--r-- | lib/exe/jsonrpc.php | 31 |
3 files changed, 117 insertions, 1 deletions
diff --git a/inc/Remote/Api.php b/inc/Remote/Api.php index 8ff38eadb..2a0178e8f 100644 --- a/inc/Remote/Api.php +++ b/inc/Remote/Api.php @@ -277,7 +277,7 @@ class Api return true; } - return auth_isMember($conf['remoteuser'], $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']); + return auth_isMember($conf['remoteuser'], $INPUT->server->str('REMOTE_USER'), (array) ($USERINFO['grps'] ?? [])); } /** diff --git a/inc/Remote/JsonRpcServer.php b/inc/Remote/JsonRpcServer.php new file mode 100644 index 000000000..00e875759 --- /dev/null +++ b/inc/Remote/JsonRpcServer.php @@ -0,0 +1,85 @@ +<?php + +namespace dokuwiki\Remote; + +/** + * Provide the Remote XMLRPC API as a JSON based API + */ +class JsonRpcServer +{ + + protected $remote; + + /** + * JsonRpcServer constructor. + */ + public function __construct() + { + $this->remote = new Api(); + $this->remote->setFileTransformation(array($this, 'toFile')); + } + + /** + * Serve the request + * + * @return mixed + * @throws RemoteException + */ + public function serve() + { + global $conf; + if (!$conf['remote']) { + http_status(404); + throw new RemoteException("JSON-RPC server not enabled.", -32605); + } + if (!empty($conf['remotecors'])) { + header('Access-Control-Allow-Origin: ' . $conf['remotecors']); + } + + global $INPUT; + + $call = $INPUT->server->str('PATH_INFO'); + $call = trim($call, '/'); + $args = json_decode(file_get_contents('php://input'), true); + if (!is_array($args)) $args = []; + + return $this->call($call, $args); + } + + /** + * Call an API method + * + * @param string $methodname + * @param array $args + * @return mixed + * @throws RemoteException + */ + public function call($methodname, $args) + { + try { + $result = $this->remote->call($methodname, $args); + return $result; + } catch (AccessDeniedException $e) { + if (!isset($_SERVER['REMOTE_USER'])) { + http_status(401); + throw new RemoteException("server error. not authorized to call method $methodname", -32603); + } else { + http_status(403); + throw new RemoteException("server error. forbidden to call the method $methodname", -32604); + } + } catch (RemoteException $e) { + http_status(400); + throw $e; + } + } + + /** + * @param string $data + * @return string + */ + public function toFile($data) + { + return base64_encode($data); + } + +} diff --git a/lib/exe/jsonrpc.php b/lib/exe/jsonrpc.php new file mode 100644 index 000000000..3852e2b45 --- /dev/null +++ b/lib/exe/jsonrpc.php @@ -0,0 +1,31 @@ +<?php + +use dokuwiki\Remote\JsonRpcServer; + +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); + +require_once(DOKU_INC . 'inc/init.php'); +session_write_close(); //close session + +header('Content-Type: application/json'); + +$server = new JsonRpcServer(); +try { + $result = [ + 'error' => [ + 'code' => 0, + 'message' => 'success' + ], + 'data' => $server->serve(), + ]; +} catch (\Exception $e) { + $result = [ + 'error' => [ + 'code' => $e->getCode(), + 'message' => $e->getMessage() + ], + 'data' => null, + ]; +} + +echo json_encode($result); |