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