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 30 $this->helper = plugin_load('helper', 'diagrams'); 31 } 32 33 /** 34 * Check all supplied diagrams and return only editable diagrams 35 * 36 * @param Doku_Event $event AJAX_CALL_UNKNOWN 37 */ 38 public function handleEditCheck(Doku_Event $event) 39 { 40 if ($event->data !== 'plugin_diagrams_mediafile_editcheck') return; 41 $event->preventDefault(); 42 $event->stopPropagation(); 43 44 global $INPUT; 45 $diagrams = (array)json_decode($INPUT->str('diagrams')); 46 47 $editable = []; 48 foreach ($diagrams as $image) { 49 $image = cleanID($image); 50 $file = mediaFN($image); 51 52 if ( 53 file_exists($file) && 54 auth_quickaclcheck($image) >= AUTH_UPLOAD && 55 $this->helper->isDiagramFile($file) 56 ) { 57 $editable[] = $image; 58 } 59 } 60 61 echo json_encode($editable); 62 } 63 64 /** 65 * Check if the given media ID is a diagram 66 * 67 * @param Doku_Event $event AJAX_CALL_UNKNOWN 68 */ 69 public function handleIsDiagramCheck(Doku_Event $event) 70 { 71 if ($event->data !== 'plugin_diagrams_mediafile_isdiagramcheck') return; 72 $event->preventDefault(); 73 $event->stopPropagation(); 74 75 global $INPUT; 76 $diagram = $INPUT->str('diagram'); 77 78 $file = mediaFN(cleanID($diagram)); 79 if (!file_exists($file)) { 80 http_status(404); 81 echo 0; 82 return; 83 } 84 85 if (!$this->helper->isDiagramFile($file)) { 86 http_status(403); 87 echo 0; 88 } 89 90 echo 1; 91 } 92 93 /** 94 * Check ACL for supplied namespace 95 * 96 * @param Doku_Event $event AJAX_CALL_UNKNOWN 97 */ 98 public function handleNamespaceCheck(Doku_Event $event) 99 { 100 if ($event->data !== 'plugin_diagrams_mediafile_nscheck') return; 101 $event->preventDefault(); 102 $event->stopPropagation(); 103 104 global $INPUT; 105 $ns = $INPUT->str('ns'); 106 107 echo json_encode(auth_quickaclcheck($ns . ':*') >= AUTH_UPLOAD); 108 } 109 110 /** 111 * Add CSP img-src directive to allow loading images from data source 112 * 113 * @param Doku_Event $event MEDIA_SENDFILE 114 */ 115 public function handleCSP(Doku_Event $event) 116 { 117 if ($event->data['ext'] === 'svg' && $this->helper->isDiagramFile($event->data['file'])) { 118 $event->data['csp']['img-src'] = "self data:"; 119 $event->data['csp']['sandbox'] = "allow-popups allow-top-navigation allow-same-origin"; 120 } 121 } 122} 123