1<?php 2/* 3 * Yurii's Gantt Plugin 4 * 5 * Copyright (C) 2020 Yurii K. 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see http://www.gnu.org/licenses 19 */ 20 21namespace dokuwiki\plugin\yuriigantt\src; 22 23use dokuwiki\plugin\yuriigantt\src\Driver\DriverInterface; 24use dokuwiki\plugin\yuriigantt\src\Entities\Link; 25use dokuwiki\plugin\yuriigantt\src\Entities\Task; 26 27 28 29class JsonRequest 30{ 31 const PERMISSIONS = AUTH_EDIT | AUTH_UPLOAD | AUTH_ADMIN; 32 33 const ACTION_UPDATE = 'update'; 34 const ACTION_DELETE = 'delete'; 35 const ACTION_CREATE = 'create'; 36 const ENTITY_TASK = 'task'; 37 const ENTITY_LINK = 'link'; 38 39 protected $payload; 40 protected $driver; 41 protected $csrf; 42 43 44 /** 45 * JsonRequest constructor. 46 * @param DriverInterface $driver 47 * @param string|null $csrf 48 * @param string|null $payload 49 */ 50 public function __construct(DriverInterface $driver, $csrf, $payload) 51 { 52 $this->csrf = $csrf; 53 $this->driver = $driver; 54 $this->payload = json_decode($payload); 55 } 56 57 58 protected function checkCSRF(&$error) 59 { 60 if ($this->csrf !== getSecurityToken()) { 61 $error = $this->error("Invalid CSRF token {$this->csrf}"); 62 return false; 63 } 64 65 return true; 66 } 67 68 69 public function handle() 70 { 71 if (!$this->checkCSRF($error)) { 72 return json_encode($error); 73 } 74 75 if (!$this->validate($error)) { 76 return json_encode($error); 77 } 78 79 $this->driver->open($this->payload->pageId); 80 81 switch ($this->payload->action) { 82 case self::ACTION_CREATE: 83 if ($this->payload->entity === self::ENTITY_TASK) { 84 $task = $this->driver->addTask(new Task($this->payload->data)); 85 $responseData = ['action' => 'inserted', 'tid' => $task->id]; 86 } elseif ($this->payload->entity === self::ENTITY_LINK) { 87 $link = $this->driver->addLink(new Link($this->payload->data)); 88 $responseData = ['action' => 'inserted', 'tid' => $link->id]; 89 } 90 break; 91 92 case self::ACTION_DELETE: 93 if ($this->payload->entity === self::ENTITY_TASK) { 94 $this->driver->deleteTask($this->payload->id); 95 $responseData = ['action' => 'deleted']; 96 } elseif ($this->payload->entity === self::ENTITY_LINK) { 97 $this->driver->deleteLink($this->payload->id); 98 $responseData = ['action' => 'deleted']; 99 } 100 break; 101 102 case self::ACTION_UPDATE: 103 if ($this->payload->entity === self::ENTITY_TASK) { 104 $this->driver->updateTask(new Task($this->payload->data)); 105 $responseData = ['action' => 'updated']; 106 } elseif ($this->payload->entity === self::ENTITY_LINK) { 107 $this->driver->updateLink(new Link($this->payload->data)); 108 $responseData = ['action' => 'updated']; 109 } 110 break; 111 112 default: 113 $responseData = $this->error('Unknown action'); 114 break; 115 } 116 117 return json_encode($responseData); 118 } 119 120 121 protected function validate(&$error) 122 { 123 if (!$this->payload) { 124 $error = $this->error('no payload'); 125 return false; 126 } 127 128 if (empty($this->payload->action) || !in_array($this->payload->action, [self::ACTION_UPDATE, self::ACTION_CREATE, self::ACTION_DELETE])) { 129 $error = $this->error('this action is not supported'); 130 return false; 131 } 132 133 if (empty($this->payload->action) || !in_array($this->payload->action, [self::ACTION_UPDATE, self::ACTION_CREATE, self::ACTION_DELETE])) { 134 $error = $this->error('this action is not supported'); 135 return false; 136 } 137 138 if (empty($this->payload->pageId) || !page_exists($this->payload->pageId)) { 139 $error = $this->error('invalid pageId'); 140 return false; 141 } 142 143 if (!(auth_quickaclcheck(cleanID($this->payload->pageId)) & self::PERMISSIONS)) { 144 $error = $this->error('you don\'t have permissions'); 145 return false; 146 } 147 148 return true; 149 } 150 151 152 protected function error($msg) 153 { 154 return ['action' => 'error', 'msg' => $msg]; 155 } 156 157 158} 159