xref: /dokuwiki/inc/Remote/JsonRpcServer.php (revision 8fae2e993b23f293b26b9cd4fd3585c9bcdb4dc1)
1<?php
2
3namespace dokuwiki\Remote;
4
5/**
6 * Provide the Remote XMLRPC API as a JSON based API
7 */
8class JsonRpcServer
9{
10
11    protected $remote;
12
13    /**
14     * JsonRpcServer constructor.
15     */
16    public function __construct()
17    {
18        $this->remote = new Api();
19        $this->remote->setFileTransformation(array($this, 'toFile'));
20    }
21
22    /**
23     * Serve the request
24     *
25     * @return mixed
26     * @throws RemoteException
27     */
28    public function serve()
29    {
30        global $conf;
31        global $INPUT;
32
33        if (!$conf['remote']) {
34            http_status(404);
35            throw new RemoteException("JSON-RPC server not enabled.", -32605);
36        }
37        if (!empty($conf['remotecors'])) {
38            header('Access-Control-Allow-Origin: ' . $conf['remotecors']);
39        }
40        if ($INPUT->server->str('REQUEST_METHOD') !== 'POST') {
41            http_status(405);
42            header('Allow: POST');
43            throw new RemoteException("JSON-RPC server only accepts POST requests.", -32606);
44        }
45        if ($INPUT->server->str('CONTENT_TYPE') !== 'application/json') {
46            http_status(415);
47            throw new RemoteException("JSON-RPC server only accepts application/json requests.", -32606);
48        }
49
50        $call = $INPUT->server->str('PATH_INFO');
51        $call = trim($call, '/');
52        $args = json_decode(file_get_contents('php://input'), true);
53        if (!is_array($args)) $args = [];
54
55        return $this->call($call, $args);
56    }
57
58    /**
59     * Call an API method
60     *
61     * @param string $methodname
62     * @param array $args
63     * @return mixed
64     * @throws RemoteException
65     */
66    public function call($methodname, $args)
67    {
68        try {
69            $result = $this->remote->call($methodname, $args);
70            return $result;
71        } catch (AccessDeniedException $e) {
72            if (!isset($_SERVER['REMOTE_USER'])) {
73                http_status(401);
74                throw new RemoteException("server error. not authorized to call method $methodname", -32603);
75            } else {
76                http_status(403);
77                throw new RemoteException("server error. forbidden to call the method $methodname", -32604);
78            }
79        } catch (RemoteException $e) {
80            http_status(400);
81            throw $e;
82        }
83    }
84
85    /**
86     * @param string $data
87     * @return string
88     */
89    public function toFile($data)
90    {
91        return base64_encode($data);
92    }
93
94}
95