xref: /plugin/diagrams/action/mediafile.php (revision 5a651f4b90f042c9b80137d5f8c16c4c9d4fb218)
1<?php
2
3use dokuwiki\plugin\diagrams\Diagrams;
4
5/**
6 * Action component of diagrams plugin
7 *
8 * This handles operations related to mediafile based diagrams
9 *
10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
11 * @author  Innovakom + CosmoCode <dokuwiki@cosmocode.de>
12 */
13class action_plugin_diagrams_mediafile extends DokuWiki_Action_Plugin
14{
15
16    /** @var helper_plugin_diagrams */
17    protected $helper;
18
19    /** @inheritDoc */
20    public function register(Doku_Event_Handler $controller)
21    {
22        // only register if mediafile mode is enabled
23        if (!($this->getConf('mode') & Diagrams::MODE_MEDIA)) return;
24
25        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleEditCheck');
26        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleNamespaceCheck');
27        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleIsDiagramCheck');
28        $controller->register_hook('MEDIA_SENDFILE', 'BEFORE', $this, 'handleCSP');
29        $controller->register_hook('PLUGIN_MOVE_HANDLERS_REGISTER', 'BEFORE', $this, 'registerMoveHandler');
30
31        $this->helper = plugin_load('helper', 'diagrams');
32    }
33
34    /**
35     * Check all supplied diagrams and return only editable diagrams
36     *
37     * @param Doku_Event $event AJAX_CALL_UNKNOWN
38     */
39    public function handleEditCheck(Doku_Event $event)
40    {
41        if ($event->data !== 'plugin_diagrams_mediafile_editcheck') return;
42        $event->preventDefault();
43        $event->stopPropagation();
44
45        global $INPUT;
46        $diagrams = (array)json_decode($INPUT->str('diagrams'));
47
48        $editable = [];
49        foreach ($diagrams as $image) {
50            $image = cleanID($image);
51            $file = mediaFN($image);
52
53            if (
54                file_exists($file) &&
55                auth_quickaclcheck($image) >= AUTH_UPLOAD &&
56                $this->helper->isDiagramFile($file)
57            ) {
58                $editable[] = $image;
59            }
60        }
61
62        echo json_encode($editable);
63    }
64
65    /**
66     * Check if the given media ID is a diagram
67     *
68     * @param Doku_Event $event AJAX_CALL_UNKNOWN
69     */
70    public function handleIsDiagramCheck(Doku_Event $event)
71    {
72        if ($event->data !== 'plugin_diagrams_mediafile_isdiagramcheck') return;
73        $event->preventDefault();
74        $event->stopPropagation();
75
76        global $INPUT;
77        $diagram = $INPUT->str('diagram');
78
79        $file = mediaFN(cleanID($diagram));
80        if (!file_exists($file)) {
81            http_status(404);
82            echo 0;
83            return;
84        }
85
86        if (!$this->helper->isDiagramFile($file)) {
87            http_status(403);
88            echo 0;
89        }
90
91        echo 1;
92    }
93
94    /**
95     * Check ACL for supplied namespace
96     *
97     * @param Doku_Event $event AJAX_CALL_UNKNOWN
98     */
99    public function handleNamespaceCheck(Doku_Event $event)
100    {
101        if ($event->data !== 'plugin_diagrams_mediafile_nscheck') return;
102        $event->preventDefault();
103        $event->stopPropagation();
104
105        global $INPUT;
106        $ns = $INPUT->str('ns');
107
108        echo json_encode(auth_quickaclcheck($ns . ':*') >= AUTH_UPLOAD);
109    }
110
111    /**
112     * Add CSP img-src directive to allow loading images from data source
113     *
114     * @param Doku_Event $event MEDIA_SENDFILE
115     */
116    public function handleCSP(Doku_Event $event)
117    {
118        if ($event->data['ext'] === 'svg' && $this->helper->isDiagramFile($event->data['file'])) {
119            $event->data['csp']['img-src'] = "self data:";
120            $event->data['csp']['sandbox'] = "allow-popups allow-top-navigation allow-same-origin";
121        }
122    }
123
124    /**
125     * Registers our handler with the move plugin
126     *
127     * @param Doku_Event $event
128     * @return void
129     */
130    public function registerMoveHandler(Doku_Event $event)
131    {
132        $event->data['handlers']['diagrams_mediafile'] = [new \syntax_plugin_diagrams_mediafile(), 'handleMove'];
133    }
134}
135