1<?php
2
3namespace Kanboard\Controller;
4
5use Kanboard\Core\Base;
6use Kanboard\Core\Controller\AccessForbiddenException;
7use Kanboard\Core\Controller\PageNotFoundException;
8
9/**
10 * Base Controller
11 *
12 * @package  Kanboard\Controller
13 * @author   Frederic Guillot
14 */
15abstract class BaseController extends Base
16{
17    /**
18     * Check if the CSRF token from the URL is correct
19     *
20     * @access protected
21     */
22    protected function checkCSRFParam()
23    {
24        if (! $this->token->validateCSRFToken($this->request->getStringParam('csrf_token'))) {
25            throw new AccessForbiddenException();
26        }
27    }
28
29    protected function checkReusableCSRFParam()
30    {
31        if (! $this->token->validateReusableCSRFToken($this->request->getRawValue('csrf_token'))) {
32            throw new AccessForbiddenException();
33        }
34    }
35
36    protected function checkReusableGETCSRFParam()
37    {
38        if (! $this->token->validateReusableCSRFToken($this->request->getStringParam('csrf_token'))) {
39            throw new AccessForbiddenException();
40        }
41    }
42
43    protected function checkCSRFForm()
44    {
45        if (! $this->token->validateCSRFToken($this->request->getRawValue('csrf_token'))) {
46            throw new AccessForbiddenException();
47        }
48    }
49
50    /**
51     * Check webhook token
52     *
53     * @access protected
54     */
55    protected function checkWebhookToken()
56    {
57        if ($this->configModel->get('webhook_token') !== $this->request->getStringParam('token')) {
58            throw AccessForbiddenException::getInstance()->withoutLayout();
59        }
60    }
61
62    /**
63     * Common method to get a task for task views
64     *
65     * @access protected
66     * @return array
67     * @throws PageNotFoundException
68     * @throws AccessForbiddenException
69     */
70    protected function getTask()
71    {
72        $project_id = $this->request->getIntegerParam('project_id');
73        $task = $this->taskFinderModel->getDetails($this->request->getIntegerParam('task_id'));
74
75        if (empty($task)) {
76            throw new PageNotFoundException();
77        }
78
79        if ($project_id !== 0 && $project_id != $task['project_id']) {
80            throw new AccessForbiddenException();
81        }
82
83        return $task;
84    }
85
86    /**
87     * Get Task or Project file
88     *
89     * @access protected
90     * @return array
91     * @throws PageNotFoundException
92     * @throws AccessForbiddenException
93     */
94    protected function getFile()
95    {
96        $task_id = $this->request->getIntegerParam('task_id');
97        $file_id = $this->request->getIntegerParam('file_id');
98        $model = 'projectFileModel';
99
100        if ($task_id > 0) {
101            $model = 'taskFileModel';
102        }
103
104        $file = $this->$model->getById($file_id);
105
106        if (empty($file)) {
107            throw new PageNotFoundException();
108        }
109
110        if (isset($file['task_id']) && $file['task_id'] != $task_id) {
111            throw new AccessForbiddenException();
112        }
113
114        $file['model'] = $model;
115        return $file;
116    }
117
118    /**
119     * Common method to get a project
120     *
121     * @access protected
122     * @param  integer      $project_id    Default project id
123     * @return array
124     * @throws PageNotFoundException
125     */
126    protected function getProject($project_id = 0)
127    {
128        $project_id = $this->request->getIntegerParam('project_id', $project_id);
129        $project = $this->projectModel->getByIdWithOwnerAndTaskCount($project_id);
130
131        if (empty($project)) {
132            throw new PageNotFoundException();
133        }
134
135        return $project;
136    }
137
138    /**
139     * Common method to get the user
140     *
141     * @access protected
142     * @return array
143     * @throws PageNotFoundException
144     * @throws AccessForbiddenException
145     */
146    protected function getUser()
147    {
148        $user = $this->userModel->getById($this->request->getIntegerParam('user_id', $this->userSession->getId()));
149
150        if (empty($user)) {
151            throw new PageNotFoundException();
152        }
153
154        if (! $this->userSession->isAdmin() && $this->userSession->getId() != $user['id']) {
155            // Always returns a 404 otherwise people might guess which user exist.
156            throw new PageNotFoundException();
157        }
158
159        return $user;
160    }
161
162    protected function getSubtask(array $task)
163    {
164        $subtask = $this->subtaskModel->getById($this->request->getIntegerParam('subtask_id'));
165
166        if (empty($subtask)) {
167            throw new PageNotFoundException();
168        }
169
170        if ($subtask['task_id'] != $task['id']) {
171            throw new AccessForbiddenException();
172        }
173
174        return $subtask;
175    }
176
177    protected function getComment(array $task)
178    {
179        $comment = $this->commentModel->getById($this->request->getIntegerParam('comment_id'));
180
181        if (empty($comment)) {
182            throw new PageNotFoundException();
183        }
184
185        if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
186            throw new AccessForbiddenException();
187        }
188
189        if ($comment['task_id'] != $task['id']) {
190            throw new AccessForbiddenException();
191        }
192
193        return $comment;
194    }
195
196    protected function getExternalTaskLink(array $task)
197    {
198        $link = $this->taskExternalLinkModel->getById($this->request->getIntegerParam('link_id'));
199
200        if (empty($link)) {
201            throw new PageNotFoundException();
202        }
203
204        if ($link['task_id'] != $task['id']) {
205            throw new AccessForbiddenException();
206        }
207
208        return $link;
209    }
210
211    protected function getInternalTaskLink(array $task)
212    {
213        $link = $this->taskLinkModel->getById($this->request->getIntegerParam('link_id'));
214
215        if (empty($link)) {
216            throw new PageNotFoundException();
217        }
218
219        if ($link['task_id'] != $task['id']) {
220            throw new AccessForbiddenException();
221        }
222
223        return $link;
224    }
225
226    protected function getColumn(array $project)
227    {
228        $column = $this->columnModel->getById($this->request->getIntegerParam('column_id'));
229
230        if (empty($column)) {
231            throw new PageNotFoundException();
232        }
233
234        if ($column['project_id'] != $project['id']) {
235            throw new AccessForbiddenException();
236        }
237
238        return $column;
239    }
240
241    protected function getSwimlane(array $project)
242    {
243        $swimlane = $this->swimlaneModel->getById($this->request->getIntegerParam('swimlane_id'));
244
245        if (empty($swimlane)) {
246            throw new PageNotFoundException();
247        }
248
249        if ($swimlane['project_id'] != $project['id']) {
250            throw new AccessForbiddenException();
251        }
252
253        return $swimlane;
254    }
255
256    protected function getCategory(array $project)
257    {
258        $category = $this->categoryModel->getById($this->request->getIntegerParam('category_id'));
259
260        if (empty($category)) {
261            throw new PageNotFoundException();
262        }
263
264        if ($category['project_id'] != $project['id']) {
265            throw new AccessForbiddenException();
266        }
267
268        return $category;
269    }
270
271    protected function getProjectTag(array $project)
272    {
273        $tag = $this->tagModel->getById($this->request->getIntegerParam('tag_id'));
274
275        if (empty($tag)) {
276            throw new PageNotFoundException();
277        }
278
279        if ($tag['project_id'] != $project['id']) {
280            throw new AccessForbiddenException();
281        }
282
283        return $tag;
284    }
285
286    protected function getAction(array $project)
287    {
288        $action = $this->actionModel->getById($this->request->getIntegerParam('action_id'));
289
290        if (empty($action)) {
291            throw new PageNotFoundException();
292        }
293
294        if ($action['project_id'] != $project['id']) {
295            throw new AccessForbiddenException();
296        }
297
298        return $action;
299    }
300
301    protected function getCustomFilter(array $project)
302    {
303        $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id'));
304
305        if (empty($filter)) {
306            throw new PageNotFoundException();
307        }
308
309        if ($filter['project_id'] != $project['id']) {
310            throw new AccessForbiddenException();
311        }
312
313        return $filter;
314    }
315
316    /**
317     * Redirect the user after the authentication
318     *
319     * @access protected
320     */
321    protected function redirectAfterLogin()
322    {
323        if (session_exists('redirectAfterLogin') && ! filter_var(session_get('redirectAfterLogin'), FILTER_VALIDATE_URL)) {
324            $redirect = session_get('redirectAfterLogin');
325            session_remove('redirectAfterLogin');
326            $this->response->redirect($redirect);
327        } else {
328            $this->response->redirect($this->helper->url->to('DashboardController', 'show'));
329        }
330    }
331}
332