forked from cosmocode/dokuwiki-plugin-diagrams
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaction.php
143 lines (125 loc) · 4.23 KB
/
action.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
/**
* Action component of diagrams plugin
*/
class action_plugin_diagrams extends DokuWiki_Action_Plugin
{
/**
* Registers a callback function for a given event
*
* @param \Doku_Event_Handler $controller
*/
public function register(Doku_Event_Handler $controller)
{
$controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'addJsinfo');
$controller->register_hook('MEDIAMANAGER_STARTED', 'AFTER', $this, 'addJsinfo');
$controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'checkConf');
$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxImages');
$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxAcl');
$controller->register_hook('MEDIA_SENDFILE', 'BEFORE', $this, 'handleCSP');
}
/**
* Add data to JSINFO: full service URL and security token used for uploading
*
* @param Doku_Event $event
*/
public function addJsinfo(Doku_Event $event)
{
global $JSINFO;
$JSINFO['sectok'] = getSecurityToken();
$JSINFO['plugins']['diagrams']['service_url'] = $this->getConf('service_url');
}
/**
* Check if DokuWiki is properly configured to handle SVG diagrams
*
* @param Doku_Event $event
*/
public function checkConf(Doku_Event $event)
{
$mime = getMimeTypes();
if (!array_key_exists('svg', $mime) || $mime['svg'] !== 'image/svg+xml') {
msg($this->getLang('missingConfig'), -1);
}
}
/**
* Check all supplied images and return only editable diagrams
*
* @param Doku_Event $event
*/
public function handleAjaxImages(Doku_Event $event)
{
if ($event->data !== 'plugin_diagrams_images') return;
$event->preventDefault();
$event->stopPropagation();
global $INPUT;
$images = $INPUT->arr('images');
echo json_encode($this->editableDiagrams($images));
}
/**
* Check ACL for supplied namespace
*
* @param Doku_Event $event
*/
public function handleAjaxAcl(Doku_Event $event)
{
if ($event->data !== 'plugin_diagrams_acl') return;
$event->preventDefault();
$event->stopPropagation();
global $INPUT;
$ns = $INPUT->str('ns');
echo json_encode(auth_quickaclcheck($ns . ':*') >= AUTH_UPLOAD);
}
/**
* Add CSP img-src directive to allow loading images from data source
*
* @param Doku_Event $event
* @return void
*/
public function handleCSP(Doku_Event $event)
{
if ($this->isDiagram($event->data['media'])) {
$event->data['csp']['img-src'] = "self data:";
$event->data['csp']['sandbox'] = "allow-popups allow-top-navigation allow-same-origin";
}
}
/**
* Return an array of diagrams editable by the current user
*
* @param array $images
* @return array
*/
protected function editableDiagrams($images)
{
$editable = [];
foreach ($images as $image) {
if (auth_quickaclcheck(cleanId($image)) >= AUTH_UPLOAD && $this->isDiagram($image)) {
$editable[] = $image;
}
}
return $editable;
}
/**
* Return true if the image is recognized as our diagram
* based on content ('embed.diagrams.net' or 'draw.io')
*
* @param string $image image id
* @return bool
*/
protected function isDiagram($image)
{
global $conf;
// strip nocache parameters from image
$image = explode('&', $image);
$image = $image[0];
$file = init_path(
$conf['mediadir'] .
DIRECTORY_SEPARATOR .
preg_replace(['/:/'], [DIRECTORY_SEPARATOR], $image)
);
if (!is_file($file)) return false;
$begin = file_get_contents($file, false, null, 0, 500);
$confServiceUrl = $this->getConf('service_url'); // like "https://diagrams.xyz.org/?embed=1&..."
$serviceHost = parse_url($confServiceUrl, PHP_URL_HOST); // Host-Portion of the Url, e.g. "diagrams.xyz.org"
return strpos($begin, 'embed.diagrams.net') || strpos($begin, 'draw.io') || strpos($begin, $serviceHost);
}
}