1f657e5d0SAndreas Gohr<?php 2f657e5d0SAndreas Gohr 3f657e5d0SAndreas Gohrnamespace dokuwiki\Remote; 4f657e5d0SAndreas Gohr 5f657e5d0SAndreas Gohr/** 6f657e5d0SAndreas Gohr * Provide the Remote XMLRPC API as a JSON based API 7f657e5d0SAndreas Gohr */ 8f657e5d0SAndreas Gohrclass JsonRpcServer 9f657e5d0SAndreas Gohr{ 10f657e5d0SAndreas Gohr protected $remote; 11f657e5d0SAndreas Gohr 12f657e5d0SAndreas Gohr /** 13f657e5d0SAndreas Gohr * JsonRpcServer constructor. 14f657e5d0SAndreas Gohr */ 15f657e5d0SAndreas Gohr public function __construct() 16f657e5d0SAndreas Gohr { 17f657e5d0SAndreas Gohr $this->remote = new Api(); 18*cf927d07Ssplitbrain $this->remote->setFileTransformation([$this, 'toFile']); 19f657e5d0SAndreas Gohr } 20f657e5d0SAndreas Gohr 21f657e5d0SAndreas Gohr /** 22f657e5d0SAndreas Gohr * Serve the request 23f657e5d0SAndreas Gohr * 24f657e5d0SAndreas Gohr * @return mixed 25f657e5d0SAndreas Gohr * @throws RemoteException 26f657e5d0SAndreas Gohr */ 27f657e5d0SAndreas Gohr public function serve() 28f657e5d0SAndreas Gohr { 29f657e5d0SAndreas Gohr global $conf; 308fae2e99SAndreas Gohr global $INPUT; 318fae2e99SAndreas Gohr 32f657e5d0SAndreas Gohr if (!$conf['remote']) { 33f657e5d0SAndreas Gohr http_status(404); 34f657e5d0SAndreas Gohr throw new RemoteException("JSON-RPC server not enabled.", -32605); 35f657e5d0SAndreas Gohr } 36f657e5d0SAndreas Gohr if (!empty($conf['remotecors'])) { 37f657e5d0SAndreas Gohr header('Access-Control-Allow-Origin: ' . $conf['remotecors']); 38f657e5d0SAndreas Gohr } 398fae2e99SAndreas Gohr if ($INPUT->server->str('REQUEST_METHOD') !== 'POST') { 408fae2e99SAndreas Gohr http_status(405); 418fae2e99SAndreas Gohr header('Allow: POST'); 428fae2e99SAndreas Gohr throw new RemoteException("JSON-RPC server only accepts POST requests.", -32606); 438fae2e99SAndreas Gohr } 448fae2e99SAndreas Gohr if ($INPUT->server->str('CONTENT_TYPE') !== 'application/json') { 458fae2e99SAndreas Gohr http_status(415); 468fae2e99SAndreas Gohr throw new RemoteException("JSON-RPC server only accepts application/json requests.", -32606); 478fae2e99SAndreas Gohr } 48f657e5d0SAndreas Gohr 49f657e5d0SAndreas Gohr $call = $INPUT->server->str('PATH_INFO'); 50f657e5d0SAndreas Gohr $call = trim($call, '/'); 5187603a0aSAndreas Gohr try { 5287603a0aSAndreas Gohr $args = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR); 5387603a0aSAndreas Gohr } catch (\Exception $e) { 5487603a0aSAndreas Gohr $args = []; 5587603a0aSAndreas Gohr } 56f657e5d0SAndreas Gohr if (!is_array($args)) $args = []; 57f657e5d0SAndreas Gohr 58f657e5d0SAndreas Gohr return $this->call($call, $args); 59f657e5d0SAndreas Gohr } 60f657e5d0SAndreas Gohr 61f657e5d0SAndreas Gohr /** 62f657e5d0SAndreas Gohr * Call an API method 63f657e5d0SAndreas Gohr * 64f657e5d0SAndreas Gohr * @param string $methodname 65f657e5d0SAndreas Gohr * @param array $args 66f657e5d0SAndreas Gohr * @return mixed 67f657e5d0SAndreas Gohr * @throws RemoteException 68f657e5d0SAndreas Gohr */ 69f657e5d0SAndreas Gohr public function call($methodname, $args) 70f657e5d0SAndreas Gohr { 71f657e5d0SAndreas Gohr try { 72f657e5d0SAndreas Gohr $result = $this->remote->call($methodname, $args); 73f657e5d0SAndreas Gohr return $result; 74f657e5d0SAndreas Gohr } catch (AccessDeniedException $e) { 75f657e5d0SAndreas Gohr if (!isset($_SERVER['REMOTE_USER'])) { 76f657e5d0SAndreas Gohr http_status(401); 77f657e5d0SAndreas Gohr throw new RemoteException("server error. not authorized to call method $methodname", -32603); 78f657e5d0SAndreas Gohr } else { 79f657e5d0SAndreas Gohr http_status(403); 80f657e5d0SAndreas Gohr throw new RemoteException("server error. forbidden to call the method $methodname", -32604); 81f657e5d0SAndreas Gohr } 82f657e5d0SAndreas Gohr } catch (RemoteException $e) { 83f657e5d0SAndreas Gohr http_status(400); 84f657e5d0SAndreas Gohr throw $e; 85f657e5d0SAndreas Gohr } 86f657e5d0SAndreas Gohr } 87f657e5d0SAndreas Gohr 88f657e5d0SAndreas Gohr /** 89f657e5d0SAndreas Gohr * @param string $data 90f657e5d0SAndreas Gohr * @return string 91f657e5d0SAndreas Gohr */ 92f657e5d0SAndreas Gohr public function toFile($data) 93f657e5d0SAndreas Gohr { 94f657e5d0SAndreas Gohr return base64_encode($data); 95f657e5d0SAndreas Gohr } 96f657e5d0SAndreas Gohr} 97