xref: /dokuwiki/inc/Remote/JsonRpcServer.php (revision cf927d07914d82d58a7663afc5d95be13e10f1a3)
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